https://adayinthelifeof.nl/A Day In The Life Of...2023-12-16T11:12:11-06:00Joshua Thijssenjthijssen@noxlogic.nlJekyllhttps://adayinthelifeof.nl/2023/12/16/more-browsers.htmlI'm still fed up and a browser is coming along fine2023-12-16T00:00:00-06:00Joshua Thijssenjthijssen@noxlogic.nl<p>Three months ago, I wrote a small story about being fed up with things and trying to do something about it. Three
months in, we’ve got a small community sharing the same goal: let’s try writing a browser.</p>
<!--more-->
<p>You have to read the previous blog post here for some background information. In a tl;dr: I’m sick and tired
of large companies doing evil stuff and turning the internet and computing into a dystopia. I decided to fight
back the only way I could: writing computer stuff.</p>
<p>That blog post wound up on HN and other resources. I tried to read most of the comments, which were very positive overall. A small one-person repo with not much in it turned into a slightly bigger repo with multiple contributors. Still, more
importantly, we gathered a small community of people who wanted to join in writing a browser. Most of them do not
have experience writing browsers and/or working with Rust. But this alone didn’t stop them from joining, discussing ideas, researching, and producing some code.</p>
<p>So, after three months, our Gosub browser is still nowhere. But that was expected, as writing a browser is not something you
can do in three months, but we’ve got research in all kinds of facets of browsers, functional code to do
HTML5 parsing, an almost finished CSS3 parser, some concepts of implementing a javascript engine, some concepts for user agents
and much more stuff.</p>
<p>We lack much, though. We’re not an organized, professional team of developers with little experience in community management.
We do not always share our views and can’t spend 8 hours a day working on this project. People have lives besides the
project, and lose interest and other things. But we are growing each day, and every day is a day closer to completion.</p>
<p>So what’s next for us? We have a few things we like to do in the short term:</p>
<ul>
<li>Create a sort of roadmap. Without this, it will be much harder to guide the project, onboard new contributors and
keep people interested. This is one of the main things I still feel we are lacking.</li>
<li>Get more people on board. Even though we are still working out the big plan on what and how we will build things,
there are still many things we could build as concepts or have multiple developers work on a single component
within the engine. This will probably start with inviting more users to our developer chat environment
at <a href="https://chat.developer.gosub.io">https://chat.developer.gosub.io</a>.</li>
<li>Research, research, research. There is so much we don’t know, and we discover more things daily.</li>
</ul>
<p>So every time in the last couple of months, whenever I saw another site being blocked because I run an ad-blocker, or being
scanned by Cloudflare and hoping I’m allowed by BigCorp to view content, or every time I feel we take a step back
from a free internet, I get behind my editor, fire up some specs, and start coding away. It might not move mountains,
but it keeps my sanity.</p>
<p>The project itself can be found on GitHub: <a href="https://github.com/gosub-browser/gosub-engine">https://github.com/gosub-browser/gosub-engine</a></p>
2023-12-16T00:00:00-06:00https://adayinthelifeof.nl/2023/09/22/browsers.htmlI'm fed up with it, so I'm writing a browser2023-09-22T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>This blogpost starts with me switching of my car radio, and ends with me writing a browser. There is some stuff
in between as well.</p>
<!--more-->
<p>Some ten years ago, I used to travel a lot by car to customers. I listened to news radio to keep myself occupied during the daily commute. In the Netherlands, I would listen to Business News Radio (BNR)
and/or Radio 1. I liked having people talk and discuss the daily news and not being interrupted by the latest music I didn’t like anyway. I think I still had a car with MP3 CDs.</p>
<p>All was well until one day, I decided to switch off my radio. I didn’t want to hear the news anymore. And that evening on the way back, the radio stayed off. I still didn’t want to listen to the news. In fact, I didn’t want to listen to the news like ever again!</p>
<p>Why? I don’t know exactly, but I don’t think it’s a coincidence that this was also around the time my wife
got pregnant (although I cannot say for sure if this was before or after we knew). But when I thought about it, the
more apparent it got: the ONLY thing you hear on the news.. any news.. are bad things(tm). War, corruption, you name it.
We still should be thankful we still call these things news because often it feels like it would be more newsworthy if
politicians weren’t corrupt, or not kept their promises, or screwed another group of people over. And the problem is
that I - as a single person - have no ways or means to do anything about it. Nothing. Not even if I tried.</p>
<p>Basically, my thinking was: if listening to the news makes me feel bad, I should stop listening to the news. Makes sense
I guess. But I went a bit further: i do not listen to the news, I also do not watch the news or browse
the internet for news. But I also actively try to get the news out of the way. We don’t watch news channels; we switch
channels when the 8 o’clock news starts (that was a thing before streaming), and I leave a room where there is news on
which I cannot control.</p>
<p>Fast forward to almost the present: I still do not watch, listen or browse the news, but I read Reddit for some subreddits that
sometimes posts news facts here and there. Any “important” news that I should need to know (do I really?) comes to me anyway because
of people. So all is well. I’m not getting saddened by the news. Job done.</p>
<p>That was until a year ago, but it’s probably way earlier that the next thing started. So although I don’t follow the classic world and political news, I do like to follow tech news, and for me, this is done 98% through Ycombinator’s hacker news. But I started to get the same feeling I had ten years ago: it’s all negative.
Companies are pushing unwanted updates, breaking all promises, raising subscriptions, and buying up companies while doing
everything in their power to figure out how much more personal data they can take (away) from us. Governments are banning
encryption because of child molesters (they also use vans and candy. Let’s also ban them!). People in power with
absolutely no idea of how the modern world works and people in power who DO know how it works, want to make it even worse for everybody else. Meanwhile, the enshitification keeps speeding up, and I’m afraid
to update my printer drivers in case my printer tells me it doesn’t like my ink and stops printing. And then there is the golden goose: the internet browser. The one place where almost everybody in the world spend their time. How long will it be until browser developers decide that ads could also shown by the browser itself, rather than from the
rendered sites that adblockers can block? We already had those.. they WILL come back. And how about browser-specific extensions that make sites unusable from other browsers (sorry, you cannot view your gmail with Firefox. Please install google chrome)? This has happened, and as soon as lawyers find a way out of monopoly issues, it will happen
again. Things like this make me sad, and again, I’m just one person out of many with little to no influence.</p>
<p>But that’s not quite right this time. This time, I DO have some influence because I am a programmer. I can develop software and I can share this software and code with others so they do not need to use it from companies that only serve their shareholders and pockets.</p>
<p>So we come to the point that I’ve decided that I am going to write a browser. For two reasons: I want this to be a way to push back. Just a tiny amount. And reason two is that I always wanted to write a browser.</p>
<p>I do not expect ANYTHING to come from this project. I do not
expect to finish this project. And I do expect that - if nobody will follow me into helping the project - the project will be dead quite soon. I do not expect this project to become the dominant browser that will topple all the big players in the market. But I do want the project to be open for non-commercial purposes. I want others to be inspired by it and make their project. And those projects will inspire others, and so on, until we DO reach a point where we have a browser that can topple the big players.
I can’t fly. I don’t have x-ray eyes. I don’t have a heavy hammer. But I can develop software. And I can share with as many people that I can. Either as an inspiration for others to write their own code, or as an example on how not to write code.</p>
<p>I’m not an idyllic person. I’m not an activist fighting for a better world or anything. But I get angry about the corporations screwing over people, software, planets. I’m not in a position to solve that. I’m just a
developer that will attempt to write a browser.</p>
<p>Details about the progress of the project can be found here: <a href="https://codemusings.nl/@jaytaph/p/MQpHToAx8c1KXyU98Auip4">https://codemusings.nl/@jaytaph/p/MQpHToAx8c1KXyU98Auip4</a></p>
<p>The project itself can be found on GitHub: <a href="https://github.com/jaytaph/gosub-browser">https://github.com/jaytaph/gosub-browser</a></p>
2023-09-22T00:00:00-05:00https://adayinthelifeof.nl/2022/09/05/100-opinions.htmlA list of 100 opinions I hold2022-09-05T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>“That’s just like, your opinion, man” - the dude</p>
<p>Here’s a list of 100 opinions I hold. These are opinions, not hard facts or truths. There will be many people disagreeing
with some of them, maybe even most of them, and there will be very few that will agree with all of them.</p>
<!--more-->
<p>[<img style="margin: 5px;" title="thedude" src="/images/opinion.gif" alt="" />]</p>
<h2 id="programming">Programming</h2>
<ul>
<li>00 - Array indices should start with 0.</li>
<li>01 - Spaces over tabs, except in Go.</li>
<li>02 - Lots of comments are good. Incorrect comments are bad.</li>
<li>03 - CQRS is not needed for your project.</li>
<li>04 - Event sourcing is not needed for your project.</li>
<li>05 - DDD is not needed for your project.</li>
<li>06 - Understand the frameworks/tools you want to use, before using them.</li>
<li>07 - Rebase locally, don’t squash merge on github.</li>
<li>08 - your projects .gitignore should not contain IDE specific directories (.vscode, .idea etc)</li>
<li>09 - Log all the things. If you didn’t log it, it didn’t happen.</li>
<li>10 - Don’t assume users are dumb. They will find things you never knew was possible.</li>
<li>11 - Spend most of the time writing the failure paths, not the happy path.</li>
<li>12 - Don’t slap on an index and call it a day. Check your queries, rewrite them and/or create indices accordingly. And hire a DBA.</li>
<li>13 - Javascript is an unreadble async mess.</li>
<li>14 - Scrum is bad</li>
<li>15 - Kanban is better</li>
<li>16 - Just because you say you do scrum, doesn’t mean you do scrum.</li>
<li>17 - you can be “agile” without daily standups, sprints, retrospectives.</li>
<li>18 - I don’t need to know what you did yesterday and doing today. I can read jira just fine thank you.</li>
<li>19 - Don’t be afraid of asking stupid questions.</li>
<li>20 - If you have problems or don’t understand something, I can help.</li>
<li>21 - I cannot help when you don’t ask.</li>
<li>22 - Write stupid programs to figure out how smart programs are written</li>
<li>23 - Try and graps at least the basics from all levels on which you work on daily (cpu, os, network etc)</li>
<li>24 - Build your own framework.</li>
<li>25 - Don’t use your own framework.</li>
<li>26 - You are not paying me for changing the 2 lines of code today, you pay me for the fact that it didn’t took 3 days and 200 extra lines.</li>
<li>27 - The more we rely on tools, frameworks and abstractions, the dumber we get.</li>
<li>28 - Most new things are just iterations of old things.</li>
<li>29 - It’s more fun to program with other than alone.</li>
<li>30 - Programming on your own can be fun too!</li>
<li>31 - You’re not Google/Facebook. Don’t write code for that scale.</li>
<li>32 - It’s ok to write scalable code. It’s often just as fast to write as non-scalable code.</li>
<li>33 - monoliths are ok. Not everything needs to consists of 50 microservices and services meshes.</li>
<li>34 - creating a microservice oriented architecture is much more complex than you think.</li>
<li>35 - Most meetings should not be a meeting.</li>
<li>36 - Having a meeting on why we should buy this 10$/m saas product is more expensive than said product for a long time.</li>
<li>37 - Sometimes developers do nothing for days and sometimes they do multiple days work in a few hours</li>
<li>38 - giving it 110% is not a sustainable pace</li>
<li>39 - Learn other programming languages</li>
<li>40 - Keep asking why</li>
<li>41 - There is no law that you need to use the latest framework/tool of the day. Older and proven tools can be fine.</li>
<li>42 - Simple is better</li>
</ul>
<h2 id="life-in-general">Life in general</h2>
<ul>
<li>43 - There are always people you hate, and there are always people who hate you.</li>
<li>44 - It’s ok to have another opion than everybody else.</li>
<li>45 - Just because you are not good in discussions, doesn’t automatically mean you’re not right.</li>
<li>46 - Don’t assume that when someone doesn’t like to speak, or doesn’t like to call, they’re automatically bad in communicating with clients.</li>
<li>47 - Always try and get underestimated by people.</li>
<li>48 - How I speak at a conference, is not the same how I speak in private, is not the same how I speak with my family.</li>
<li>49 - Family & health before everything.</li>
<li>50 - Your boss is not your family, unless you are in the family business.</li>
<li>51 - It’s ok to fail</li>
</ul>
<h2 id="php-programming">PHP programming</h2>
<ul>
<li>52 - PHP used to be a fractal of bad design.</li>
<li>53 - PHP doesn’t need generics, or functional idoms, or async.</li>
<li>54 - PHP can do long running processes, it’s just that most frameworks/code can’t.</li>
<li>55 - There are lots of smart PHP developers.</li>
<li>56 - I’m not a smart PHP developer.</li>
<li>57 - Protected properties and functions over private. No need to close down your code just because you want to. Developers are quite capable to assess when and where to reuse your code how they seem fit.</li>
<li>58 - Constructor property promotion is a ridiculous way to save 3 lines of code in a non-readable way.</li>
<li>59 - Symfony > Laravel</li>
<li>60 - There is too much magic in Laravel to make it intuitive.</li>
<li>61 - Eloquent/ActiveRecord is an abomination</li>
<li>62 - Doctrine/Data mapper is better, but not by much.</li>
<li>63 - You should know SQL. I’ll settle for knowning an inner from an outer join.</li>
<li>64 - You do not need to write everything with DQL. Raw SQL is sometimes the better choice.</li>
<li>65 - You should use Xdebug. Using var_dump is like that game guessing a person by just asking yes/no questions.</li>
<li>66 - Sometimes var_dumping is quite ok. Know when to use which tool.</li>
<li>67 - Use phpcs, phpstan and phpmd.</li>
<li>68 - Don’t (s)ftp your files to production</li>
<li>69 - The spaceship operator (<=>) is the most useless functionality of php</li>
<li>70 - Many things can go wrong when not considering user input. Use frameworks and tools to handle this. Don’t parse your own user input.</li>
<li>71 - SQL injection is still a thing</li>
</ul>
<h2 id="cloud--ops">Cloud & Ops</h2>
<ul>
<li>72 - There is always a setting in AWS you didn’t know about.</li>
<li>73 - AWS is a cheap and fast way to boot up infrastructure.</li>
<li>74 - AWS is an expensive way to continue running your business.</li>
<li>75 - AWS > GCP</li>
<li>76 - GCP > Azure</li>
<li>77 - Everything > Azure</li>
<li>78 - You don’t need to setup a lambda to push a message to SNS that calls another lambda to send it to DynamoDb in order to get things done.</li>
<li>79 - Lesser AWS parts is better.</li>
<li>80 - If you need to ask whether you should use kubernetes or not, then the answer is automatically no.</li>
<li>81 - 99% of the projects running kubernetes do not need kubernetes.</li>
<li>82 - Kubernetes is your best friend, until it decides to become a serial killer and tries to hunt you down.</li>
<li>83 - Regular VMs are ok.</li>
<li>84 - Docker is fine, not using docker is equally fine.</li>
<li>85 - Understand the implication when Google decides to disable your account (for whatever reason).</li>
<li>86 - DevOps is not a job title, role or department.</li>
</ul>
<h2 id="sysadmin">Sysadmin</h2>
<ul>
<li>87 - Flying a plane is easy, it’s when things go wrong is when pilots earn their money. Same thing applies to system administrators</li>
<li>88 - I don’t like systemd.</li>
<li>89 - I don’t like snap.</li>
<li>90 - Install mc on every machine you possibly can.</li>
<li>91 - Installing a mail server isn’t THAT hard.</li>
<li>92 - It’s perfectly find to run DirectAdmin in some cases.</li>
<li>93 - WSL2 is not great, not terrible.</li>
<li>94 - Don’t use ansible for providing 1000 machines.</li>
<li>95 - Don’t use puppet for providing 2 machines.</li>
<li>96 - Don’t use chef</li>
<li>97 - If you don’t check your backup, you might as well not do the backup.</li>
<li>98 - I should check my backups more often.</li>
<li>99 - It’s usually DNS</li>
</ul>
2022-09-05T00:00:00-05:00https://adayinthelifeof.nl/2021/12/27/a-comprehensive-list-of-failed-projects.htmlA comprehensive list of failed projects2021-12-27T00:00:00-06:00Joshua Thijssenjthijssen@noxlogic.nl<p>I’m full of ideas. Most of them are stupid, though. But sometimes, some of these ideas get stuck in my head like an itch I must scratch, and voila: a new side-project is born.</p>
<p>I don’t start projects with a direct goal. Sometimes it’s just to figure out: “how hard could it be” (hint: always),
or sometimes: I could get rich with this (hint: never).</p>
<p>Even though I’m making a good amount of money as a freelance consultant, I would love to have a project that I love to
work on, which generates money even when I’m not working on it directly. As a freelancer, I can only bill for the hours I
make, and typing twice as fast doesn’t reflect in getting paid twice as much.</p>
<p>Because I make good money, I also have the opportunity to take a few months off in a year and focus full time on my
side projects. For me, this is also a perfect way to wind down after hectic months of working against deadlines, so it
helps me destress, feeds my curiosity, allows me to use new untapped technologies, and maybe make a bit of money.</p>
<p>If we talk about the first few reasons: all my projects succeed, whether I finish them, get bored with them, or
find they are not feasible to keep alive. However, making money is much harder to achieve, yet <br />
it is becoming the main reason I want to start a new project.</p>
<!--more-->
<p>Here is a list of projects I have worked on for a significant amount of time from 1998 until 2021.</p>
<ul>
<li>CybOS - an operating system from scratch.</li>
<li>Saffire - a programming language.</li>
<li>EZShopping - An e-commerce SaaS.</li>
<li>Techanalyze - an online assessment and reporting tool.</li>
<li>DutchTechRecruitment - a recruitment platform crossed with a dating app.</li>
<li>Seams-CMS - A headless CMS system.</li>
<li>Symfony Rainbow Series - A 7-part series about the Symfony framework.</li>
<li>Rest cookbook - A recipe site about REST.</li>
<li>Commodore64 simulator - A working commodore 64 emulator written in PHP.</li>
<li>BitMealum - A e2e encrypted email alternative.</li>
<li>Leita - a web security scanner</li>
</ul>
<p><br /></p>
<h1 id="cybos---an-operating-system-from-scratch">CybOS - an operating system from scratch.</h1>
<p>I’ve always been fascinated with assembly and low-level programming. Back in 1998, I’ve started to begin writing an
operating system in C (with some assembly). Back in these days, we didn’t really have any (good) emulators, so most of
the time was spent compiling, writing code to floppy disk, booting up another PC, and seeing if it works.</p>
<p>It uses a custom bootloader (so no grub), and it’s capable of most of the basic functionality like memory management,
scheduling, disk I/O and having a VFS capable of loading ext2, cybfs (custom simple format), and fat.</p>
<p>The system is/was at a point it was ready to get a toolchain running on it. Instead of writing your custom C compiler
and linker, you could use newlib for this, where you only need to provide the “glue” between your OS and newlib.
It should be “simple”, but it wasn’t at that time, so I kinda lost interest in the project.</p>
<p>Source code can be found at: <i class="fab fa-github"></i> <a href="https://github.com/jaytaph/cybos">https://github.com/jaytaph/cybos</a></p>
<p><br /></p>
<h1 id="saffire---a-programming-language">Saffire - a programming language.</h1>
<p>I bought <a href="https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools">the purple dragon</a> and obviously,
when you have the purple dragon, you MUST create your own programming language.</p>
<p>I wanted a language that felt like PHP, but somehow would work more like Python and ruby. So I’ve created a language
that was interpreted, dynamically strong typed, and with everything as an object.</p>
<p>It was one of the first projects I worked on, where some people (some of which I didn’t know) gathered around an IRC
channel back then. It didn’t result in a lot of extra hands on the code, But having a few people around allows discussing the issues I tend to ran into (a lot). When you hit a snag, it’s good to have
people around that think about the problem differently or provide solutions you by yourself never thought about. But ultimately, being alone in writing code gets lonely and can destroys the enthousiasm quickly.</p>
<p>Source code can be found at: <i class="fab fa-github"></i> <a href="https://github.com/saffire">https://github.com/saffire</a></p>
<p><br /></p>
<h1 id="ezshopping---an-e-commerce-saas">EZShopping - An e-commerce SaaS</h1>
<p>In 2003/2004, I started my first real company with my brother and a common friend of ours. We created a
platform to create your own e-commerce site easily. Even though it seems a very common piece of software now, there weren’t many options back then. OSCommerce was there, but no real SaaS solutions. We spend about a year or so
building the software, with me writing the software and the two others doing sales and marketing. We had a few customers
but ultimately didn’t gain a critical number of customers to hit it off. (as a few young kids without any form
of money). Eventually, we had some internal conflicts and closed down the company.</p>
<p>Even though commercially a failure, I learned so much about running a business. In hindsight, we should have been more
proactive towards prospects (we had a really cool information package, which we send out a lot to interested companies
every week by post), but we didn’t got people into actually buying our subscriptions.</p>
<p><br /></p>
<h1 id="techanalyze---online-assessments">Techanalyze - online assessments</h1>
<p>Techanalyze was a company I started with a colleague freelancer I have known for a while. We occasionally worked
together on projects, and we were thinking about writing a system that could assess developers (and others) based on
technical interviews.</p>
<p>We started this as a business, and we worked on the platform. Things were kept simple: a PHP/Symfony platform
running on a VPS kept our costs very low. Since we are both developers and not sales/marketing people, we (again) hit
a wall on getting clients for our platform. We spent a lot of time and effort getting people to use our platform,
but it didn’t gain much traction. Fortunately, one customer for who we created a white-label instance of our
platform was willing to buy our intellectual property, so in the end, we were bought for an ok sum of money. We
didn’t get rich from it, but we learned the harsh lesson that having a platform doesn’t mean you can sell a platform.</p>
<p><br /></p>
<h1 id="dutchtechrecruitment">DutchTechRecruitment</h1>
<p>We had a wild idea where we wanted to do recruitment the same way as dating apps. Based on your preferences, we
would match job openings to your likings. Codewise, this was a pretty decent system, where we calculated scoring based
on your preferences.</p>
<p>We had a few problems getting this up and running: first of all, we ran into a chicken and egg problem: we needed job
openings and users, but getting one without the other was difficult to pull off. Then, again, our lack of
sales/marketing skills didn’t help either.</p>
<p><br /></p>
<h1 id="seams-cms---a-headless-cms-system">Seams-CMS - A headless CMS system.</h1>
<p>While I was doing a job for a client, one of the things we needed to do was to implement a headless CMS system into our
current platform. Unfortunately, during the time we spent finding the correct CMS system, we found that many of them,.. well.. suck.
So we were playing with the idea of how hard it would be to create our own?</p>
<p>I asked a frontend developer to join me, and together we started working on a system. Unfortunately, we didn’t<br />
match and parted ways, but not without introducing me to React. Even though I dislike anything javascript, I was
impressed with how flexible react was and where even I could write a flexible frontend with ease.</p>
<p>I learned that you need a partner or partners with the same idea or mindset you have. While my mindset was more
on - getting things out as soon as possible - my partner’s was more about: let’s try neat and new tech and see
what happens. Both visions are understandable: mine was about creating a project that would make money, his idea was
about creating a project where he had the freedom to use tools and techniques he couldn’t use in his daily work.</p>
<p>Once we had our platform up and running: you might already guess - no customers. I’ve dived into learning a lot about
marketing and sales, but ultimately decided I couldn’t do it alone.
I’ve asked a few marketing companies nearby to see what they could do to help out. Still, the amount of money they asked
for was just way too much I could spend, and most of the ideas I heard were: doing a bit of SEO, paying a lot of money to
google ads, and setting up a Facebook account. I’m not sure that would be the wisest way to spend my money, so I
ultimately decided not to try such a significant (financial) risk.</p>
<p><br /></p>
<h1 id="symfony-rainbow-series">Symfony Rainbow Series</h1>
<p>I <em>LOVE</em> spending time in the depths of software, figuring out how things work. One of the things I kept on hitting was
that I could not completely understand how Symfony’s framework security component worked. So, I’ve created a
blog post about it, which is a way to try to understand things. However, this post was getting so ridiculously
large, and I turned it into a 200+ page book published on LeanPub.</p>
<p>I’ve already got some experience with writing, as I’ve written a book before and was published by phparchitect.</p>
<p>So I’ve done the publishing myself, and I’ve released the book on Leanpub but also created hard copies with a local printing press. The book sold
pretty well, especially given the niche market. So I’ve decided to write more.
I’ve written another book about the Symfony Console component (a lot fewer pages). And I’ve spent a lot of time writing
the third book about Symfony Forms. I’ve written about 300 pages, at which point I’ve hit writer’s block (it’s a real
thing!). I’ve turned around the book’s structure maybe ten times. Rewritten complete chapters, but I couldn’t
finish it anymore. Ultimately, I’ve decided to let the book rest and started on a Symfony form recipe book, where I
wrote solutions for about 25 common problems with Symfony forms. I hoped this would reboot my writing on the
main Symfony forms book. But this never happened. I never completed the book, although it was finished for about 95%.</p>
<p>One thing that I loved about the books is that they worked well for me as a freelancer. I was suddenly seen as a
go-to expert for all things complex with Symfony, which resulted in many (high-paying) consultancy jobs. So even
though the books themselves probably didn’t make a profit, considering the hours spent on them. I think I got a lot of
revenue by getting a lot of excellent projects in the end.</p>
<p><br /></p>
<h1 id="rest-cookbook---a-recipe-site-about-rest">Rest cookbook - A recipe site about REST.</h1>
<p>Back in the days where APIs should be RESTful, I’ve created a simple (static) site with a few recipes about how to do
things restful. There are about 15 recipes on there, and my idea was to create at least one recipe per week. Resulting
in over 100 recipes over two years. This, plus all the contributions from the people, would help me write more
recipes, as the site itself was open source.</p>
<p>Over time, I think I’ve got only a handful of pull requests, and even those were mostly fixing spelling errors. I lost
interest in writing recipes myself, so the site itself is just a small list of recipes. Funny though: it’s my
most visited site and has a lot of backlinks from stackoverflow and even Wikipedia. So somehow, people have seen to
find their way to the site.</p>
<p>See the cookbook at: <i class="fas fa-globe"></i> <a href="https://restcookbook.com/">https://restcookbook.com/</a></p>
<p><br /></p>
<h1 id="commodore-64-simulator">Commodore 64 simulator</h1>
<p>My first computer was a C64, and on occasion, I fire up an emulator and dabble a bit in 650x assembly. Just for fun, I
tried to see if I could write an emulator of a C64 in PHP. It turns out: you can.</p>
<p>The emulator itself runs a completely functional C64, so you can play games, and it even runs a dedicated 6502 CPU
test suite with all the valid (and invalid) opcodes and addressing available.</p>
<p>One of the downsides of writing such a thing in PHP is that PHP doesn’t have a real output system.
There is PHP GTK, but this needs to be compiled, which most people haven’t. So I’ve written a python/pygame window
that outputs the video “signal”, where the signal was an IPC memory block between the PHP code and Python.</p>
<p>It was very slow, but still fast enough to see running some games. There were two main problems: first, I
never got around writing the SID sound code, but more importantly, I got stuck with keyboard mapping (basically emulating
the IO chips). Second, I couldn’t make sense of the actual schematics and documentation, and basically, the few people I went to
for advice told me this was way above their heads. So I got stuck and never finished it.</p>
<p>Find it here: <i class="fab fa-github"></i> <a href="https://github.com/jaytaph/c64php">https://github.com/jaytaph/c64php</a></p>
<p><br /></p>
<h1 id="bitmaelum---a-e2e-encrypted-email-alternative">BitMaelum - A e2e encrypted email alternative.</h1>
<p>This is still one of the coolest projects I’ve started. It’s an email alternative that deals once and for all with
address ownership, privacy, spam, and many other things. I’ve started writing this in Go. I’ve got one contributor
with me (Thanks, Antonio!), which helped me with good ideas, testing, bug fixing, and the occasional code. It made me happy to find that I could talk to somebody with the same enthusiasm about a project.</p>
<p>I still think this is a super sweet project, and though it still has a few problems to solve, it’s capable of a lot of
things already. Unfortunately, however, I couldn’t work on it for a while due to time, and the project faded away.</p>
<p>Find the code at: <i class="fab fa-github"></i> <a href="https://github.com/bitmaelum/bitmaelum-suite">https://github.com/bitmaelum/bitmaelum-suite</a> and <i class="fas fa-globe"></i> <a href="https://bitmaelum.org">https://bitmaelum.org</a></p>
<p><br /></p>
<h1 id="leita---a-web-security-scanner">Leita - a web security scanner</h1>
<p>I’m currently working on another project: a website security scanner. Basically, we run all kinds of tools automatically
and generate a nice report to reflect the state of your website/domains.</p>
<p>We will add more stuff, like application testing and OWASP stuff so that you can get in-depth scans of your systems at
regular intervals.</p>
<p>Again, this is also a project I work on in my spare time, with the help of one person who helps me around a bit, but in a much slower speed and less enthousiasm. I’m grateful, though, but I feel we could get more out of it.</p>
<p>Find it at: <i class="fas fa-globe"></i> <a href="https://leita.io">https://leita.io</a> (still in early stage beta testing).</p>
<p><br /></p>
<h1 id="enthousiasm-and-loneliness-are-killing-factors">Enthousiasm and loneliness are killing factors</h1>
<p>There are two reasons why these projects mostly fail in my experience. First, I work in two modes: complete
standstill and lightning speed. When I’m starting a new project, I’m so enthusiastic; I spend every free hour
working on the code, thinking about new ideas and such. I think this pace is way too fast for everyone who
wants to join me, which complicates things a lot. People don’t seem to keep up and lose interest quickly.</p>
<p>Another reason is the lack of - well - friends, I guess. I have a severe form of autism which not only controls the way
I need to work (both professionally and for fun), but it also puts me a bit in social isolation. Not to complain, though,
I like being on myself, and I have a lovely wife and kids, so I never feel or am alone. However, when it comes to
“computer stuff”, I don’t have anyone I can talk to. This makes it harder to talk about issues
and problems I’m facing. Often, in my professional work, I’m the expert/consultant who comes in when things get too
tricky, so by default, I don’t have a lot of people around me to ask for help. Bummer.</p>
<p>So this reflects in my projects as well. I start something, hoping to get others enthusiastic about it as
well, but I have no idea how to reach those people. I suck at marketing/sales, even when I’m selling myself I guess :)</p>
<p>Any project, aimed as a hobby side-project or trying to make money, needs more than just a good idea, enthusiasm, and code. It needs to be sold. It needs to be tailored to potential customers, and it needs to be marketed in the right
areas for the right people. Otherwise, it will be just another entry in a (long) list of projects that didn’t go
anywhere.</p>
<p>I’ve got the technical side covered. I just don’t know how to find people who can help with the “rest”.</p>
2021-12-27T00:00:00-06:00https://adayinthelifeof.nl/2021/11/07/lets-talk-about-your-privates.htmlLet's talk about your privates2021-11-07T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>In the software development world, there are a lot of debates going on: tabs vs. spaces, vim vs. emacs, Linux vs. mac, and so on. In most, if not all, these debates, there is no clear winner: both sides are equally right (or wrong), and most likely, there is no majority on one side. I, however, am part of a debate on the “losing” side in such that I’m part of
the minority. And even though strong opinions are weakly held, after I guess since the launch of PHP 5, my opinion still holds, and I’m talking about your privates…</p>
<!--more-->
<p>Here is the whole debate:</p>
<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="cp"><?php</span>
<span class="kd">class</span> <span class="nc">Foo</span> <span class="p">{</span>
<span class="cd">/** protected or private? */</span>
<span class="n">string</span> <span class="nv">$bar</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>Should this <code class="language-plaintext highlighter-rouge">$bar</code> property be protected or private? I think the correct answer would be “it depends”, but my answer would
be “protected by default,” while the majority of users would opt for “private by default.” I think this is the wrong way
of looking at the issue. So let’s explain why I think why this is.</p>
<h3 id="visibility">Visibility</h3>
<p>To decide what the best visibility is, we need to know the difference between protected and private. In a nutshell:
Protected means that the property (or method) cannot be accessed from code OUTSIDE the existing class. However, classes that EXTEND the given class CAN access the property or method. Private means that even classes that extend this class cannot access the property. It’s private to this specific class alone.</p>
<h3 id="why-private">Why private?</h3>
<p>So why is the majority of users using private? More than often, it’s because “it is the way.” There is no actual reasoning behind it when you ask the question. Still, it most likely boils down to maintainability for those who have a reason: it’s much easier to refactor a class that you are 100% confident is not referenced outside the class.
And this is true! It makes a lot of sense: if you write a library and open-source it, there is no real way of knowing who is using your code, and changing a method or property can break a lot of code from your users. There is merit in
making everything private because it allows a lot of flexibility for you and your class.</p>
<h3 id="why-protected">Why protected?</h3>
<p>One simple reason: You should not decide for me how I use your library or code. That’s it.</p>
<p>A library can be built for many use-cases, but it’s a 100% certainty that you as a developer do not know ALL the use-cases your library may be used or abused for. Some of these use-cases could be plain stupid, and some of these use-cases are entirely valid. The point is: by making your properties and methods private, you just decided for ALL
YOUR USERS that your library is not to be used in a way that you didn’t think of beforehand.</p>
<p>Sure, you can create an issue or PR to change private into protected as soon as you find a use case. But let me know how that works in practice.
The times this is done in those libraries are rare, and of course, you can fork the lib, but now you have to take responsibility for ALL library code, including security issues and whatnot. And maintain more code is precisely what we want in life.</p>
<h3 id="what-about-composition-over-inheritance">What about composition over inheritance?</h3>
<p>Well, I agree. Composition should be used over inheritance. But it’s OVER inheritance, not INSTEAD OF inheritance. There are many use-cases where inheritance is valid, even the only option.</p>
<h3 id="how-about-the-practical-side-of-things">How about the practical side of things?</h3>
<p>I’ve been bitten by final/private many, many times over. By small libs and by large frameworks and libraries. I’ve been bitten by protected, well.. never. I do not know of any other person who is bitten by my love for protected visibility.
Often I have a library that does exactly what I want until it doesn’t. And very often, it’s a straightforward fix to make
sure it does work: if only I could extend this class and override this method :( Instead, now I have to copy/paste an entire class, update a single method, often even a single line and maintain this piece of code into eternity.</p>
<h3 id="but-my-users-are-complaining-about-breaks">But my users are complaining about breaks!</h3>
<p>Here is the thing: IF you are doing a BC break, any BC break, you should use semver and upgrade your major release number. But protected does something else intentionally: it moves the responsibility of <strong>USAGE</strong> from the library writer to the library user. Protected says: “Hey if you need to do something I didn’t foresee, here is the tooling. But know that you
are on your own!”.
And I kind of like this attitude: it allows users who do not want this responsibility to use your library the way
they always have done. Nothing is changing or is more dangerous now that we use protected. We just more your code more open. And it will enable those power users can change the 1% of your library without rewriting the other 99%.
I think this is a clear win, but somehow, we are indoctrinated that we should care for our users like children who cannot take care of themselves. We need to educate people on why things are dangerous, instead of saying: this is dangerous, and I will take it away from you so you can’t hurt yourself.</p>
<h3 id="eating-your-own-dogfood">Eating your own dogfood</h3>
<p>If you look at some of my open-source libraries, you might see that I’m using privates as well. Why is this? The first time I use protected, within 5 minutes, there will be a pull request or an issue opened about changing it to private. And now we are in a debate with people that I don’t feel like I need to have over and over again. It gets too tiresome. There are too many battles I (want to) fight, and this is one too many.</p>
2021-11-07T00:00:00-05:00https://adayinthelifeof.nl/2021/09/01/first-game-with-unity.htmlMy first attempts with Unity2021-09-01T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>For a while now, I’m thinking about doing something with Unity to see how it works. And what
a better way to figure things out is to try and develop a game with it.</p>
<!--more-->
<h1 id="the-idea">The idea</h1>
<p>The main idea was M.C. Escher’s lithography <a href="https://en.wikipedia.org/wiki/Relativity_(M._C._Escher)">‘Relativity’</a>, the one with the stairs going in all directions.</p>
<figure class="image">
<img title="Relativity by M.C. Escher" src="/images/kuubed/relativity.jpg" width="200" />
<figcaption>Relativity by M.C. Escher</figcaption>
</figure>
<p>I wanted to make a cube that can rotate in any direction and where you must collect stuff as a player inside the cube. So, when you are at the bottom of the cube and see
a coin at the ceiling, rotating the cube 180 degrees will make the coin get to the floor where you can collect it. You would need to walk on a platform, and based on how the cube
rotates, and you can walk at the top or bottom of the platform (think David Bowie in Labyrinth).</p>
<p>So, to start, I fired up Unity without knowing what it is and does. Fortunately, there are some really
great tutorials on how to begin with Unity, and pretty soon, I had a simple floor with a texture and some initial blocks on the screen.</p>
<table class="img_table">
<tr><td>
<figure class="image">
<img title="Simple cubes stacked together on a plain" src="/images/kuubed/image1.png" width="400" />
<figcaption>Simple cubes stacked together on a plain</figcaption>
</figure>
</td><td>
<figure class="image">
<img title="These random placed blocks turned out to be a level as well!" src="/images/kuubed/image2.png" width="400" />
<figcaption>These random placed blocks turned out to be a level as well!</figcaption>
</figure>
</td></tr>
</table>
<p>I found some fantastic prefabs on the Unity Asset store, lots of them that can be used for free (with some attribution), so I found a few that I like (and still have in the game):</p>
<ul>
<li>A low-poly astronaut with neat animations on it, which I currently have no idea how to use.</li>
<li>Some items like flasks and coins, which nicely spin and bob around.</li>
</ul>
<figure class="image">
<img title="It starts to look like a game" src="/images/kuubed/image3.png" width="800" />
<figcaption>It starts to look like a game</figcaption>
</figure>
<p><br />
<br />
<br /></p>
<h1 id="the-canvas">The canvas</h1>
<p>One tricky thing I couldn’t understand when first using Unity is how to get something like score, time, etc., on the screen. It turns out that you have a camera where you look through onto your game world, and you can “stick” a 2d transparent canvas in front of the camera. On this canvas, you can add images, text, your menu system, etc. There are probably other
ways maybe, but in 3d-world, this seems the way to go.</p>
<p>So I’ve added a canvas, some counters like coins left and time left. And some buttons to control the cube in the X, Y, and Z direction (not working yet, though).</p>
<figure class="image">
<img title="Some initial canvas elements on the screen" src="/images/kuubed/image4.png" width="800" />
<figcaption>Some initial canvas elements on the screen</figcaption>
</figure>
<p>I also changed the camera position a bit, so it shows the field in an isometric way. It just looks more likable and gives the player a bit more
overview of the puzzle.</p>
<figure class="image">
<img title="By changing the camera a bit, it's easier and nicer to play" src="/images/kuubed/image5.jpeg" width="800" />
<figcaption>By changing the camera a bit, it's easier and nicer to play</figcaption>
</figure>
<p><br />
<br />
<br /></p>
<h1 id="the-level-editor">The level editor</h1>
<p>One thing I figured out that I needed was a level editor. It would be a simple setup to move in a cube and add elements like blocks, coins, etc. This data will be serialized (how?) into a JSON format (what format?) so we can load this
into our level.</p>
<p>So from very soon on, I decided I didn’t have many scenes, where each scene was a single level, but one single “level”-scene,
which automatically loads the level through a specified JSON file. Not the easiest thing to begin with, but no need to worry
about that right now.</p>
<p>The level editor would be and stay simple:</p>
<figure class="image">
<img title="Moving a cursor and placing blocks work" src="/images/kuubed/image6.png" width="800" />
<figcaption>Moving a cursor and placing blocks work</figcaption>
</figure>
<figure class="image">
<img title="The editor allows you to add different elements" src="/images/kuubed/image7.jpeg" width="800" />
<figcaption>The editor allows you to add different elements</figcaption>
</figure>
<figure class="image">
<img title="Changing around some of the interface" src="/images/kuubed/image9.png" width="800" />
<figcaption>Changing around some of the interface</figcaption>
</figure>
<p>Since there was still a lot to do before I could even consider loading and saving the data from the editor, I created a
“playground” scene, which was a copy of the level scene, but where I manually made a level inside. This way, I could
continue testing things like cube rotations and player movements without worrying much about all the other not-so-important
stuff (in hindsight, I shouldn’t build a level-editor this soon, but it turns out that a lot of knowledge was
harvested from creating the editor, which would have taken longer if I didn’t do it).</p>
<p><br />
<br /></p>
<h1 id="slowly-going-forward">Slowly going forward</h1>
<p>One of the hardest things to get right was the movement. Since we are inside a cube, movement is done grid-based too. This was not the best idea because we need to fixate our player on specific positions while movement should be fluent. For example, what happens when a user hits a key when the player moves from one block to another. What if we move forward
into the abyss? How do we keep the player straight while still using the physics engine of Unity?</p>
<p>This turned out to be a big issue where I constantly switched from a character control (more control, no gravity stuff)
to a rigid body system (less control, more done by the physics engine, nice gravity, etc.).</p>
<p>Either things would work, but jumping looked awful, and we had to do manually code gravity. Or we leave things
to the physics engine, hoping we don’t slide of blocks and such.</p>
<p>It turns out that with tweaking of the rigid body component, I finally got something that worked: we could move (although not quite precise) from block to block. We had a scanner that checks if we can make a move forward (only if there is not a block
in front of us) etc.</p>
<p>A friend of mine suggested using DOTween for the movement of the player. This turned out to be a great tip because now I could say: move my player from block (1,1,1) to block (2,1,1) and do this in a smooth movement.
Also, jumping worked nicely without any hassle.</p>
<p>But there are other things to think about with the movement: how are we allowed to move? What happens when we jump? How can we jump onto a block, how can we jump over an abyss, etc.? Lots of these things seem obvious until you have to code them
and then you have to think about it.</p>
<figure class="image">
<img title="Writing on paper how movement works " src="/images/kuubed/image27.jpeg" width="800" />
<figcaption>Writing on paper how movement works </figcaption>
</figure>
<p><br />
<br /></p>
<h1 id="rotating-the-cubefield">Rotating the cube/field</h1>
<p>So next up is the cube rotation. Here is where things started to change: I didn’t have a cube (yet), but it turned out that
just the blocks inside the cube would suffice as a game level. This way, I could fall into the abyss (or floor), so
being inside a cube was unnecessary. Still, I wanted the cube sides to be part of some puzzles (inside a closed cube,
you cannot fall into the abyss, for instance), so I kept this as an option later.</p>
<p>I also browsed through the Unity Asset store and found a cool (and free!) Aztec/jungle/temple theme that contained blocks. Immediately the whole level looked a lot nicer!</p>
<figure class="image">
<img title="I was thinking about moving the cube inside a temple, but I'm not good at designing that stuff" src="/images/kuubed/image10.jpeg" width="800" />
<figcaption>I was thinking about moving the cube inside a temple, but I'm not good at designing that stuff</figcaption>
</figure>
<p>Also, I found a way to get the player’s animation going during movement, so when the player jumps up, you see the astronaut lifting its arms and landing on its feet back. I just needed to implement the running/walking animations on
the block movements.</p>
<p><br />
<br /></p>
<h1 id="the-main-menu">The main menu</h1>
<p>Time for the main menu, the place where you enter the game. Here some real canvas magic happens, mostly done thanks to tutorials found on youtube. After actually understanding the canvas system much better, I took on to create
the different panels like an options panel, credits panel, select-your-level panel, etc.</p>
<table class="img_table">
<tr><td>
<figure class="image">
<img title="This 'setup' is taken from a tutorial" src="/images/kuubed/image11.png" width="400" />
<figcaption>This 'setup' is taken from a tutorial</figcaption>
</figure>
</td><td>
<figure class="image">
<img title="The options menu" src="/images/kuubed/image12.png" width="400" />
<figcaption>The options menu</figcaption>
</figure>
</td></tr>
</table>
<table class="img_table">
<tr><td>
<figure class="image">
<img title="A scrolling credits panel" src="/images/kuubed/image13.png" width="400" />
<figcaption>A scrolling credits panel</figcaption>
</figure>
</td><td>
<figure class="image">
<img title="Trying to get the menus look nice on both landscape and portrait" src="/images/kuubed/image14.png" width="400" />
<figcaption>Trying to get the menus look nice on both landscape and portrait</figcaption>
</figure>
</td></tr>
</table>
<p>Even though I was proud enough to get it going, it took a lot (A LOT) of effort to work in different aspect ratios, resolutions, mobile formats, landscape, portrait,.. and even switching between them. Nowadays, it probably takes 10 minutes, but learning the different components and how the settings interact with each other takes a
long time.</p>
<p>I wasn’t also pleased with the designs, so I got onto Fiverr and found <a href="https://www.fiverr.com/aneeskhan721">Anneskhan721</a> who could create nice looking panels.</p>
<table class="img_table">
<tr><td>
<figure class="image">
<img title="The old UI" src="/images/kuubed/image16.jpeg" width="400" />
<figcaption>The old UI</figcaption>
</figure>
</td><td>
<figure class="image">
<img title="And new designed UI" src="/images/kuubed/image15.jpeg" width="400" />
<figcaption>And new designed UI</figcaption>
</figure>
</td></tr>
</table>
<p>By this time, I started experimenting with localization. Even though it’s a preview package in Unity (but very close to a stable release), it seems to work
nicely without too much effort.</p>
<p>I found in Unity itself that once you get the hang of like 10% of a system, the rest is easy to follow and understand.</p>
<p><br />
<br /></p>
<h1 id="controls">Controls</h1>
<p>Controls were tricky since I’ve moved halfway through the game from the default Input system to the new Unity input system. Although much more complex to set up correctly, it makes it easier to add all kinds of input devices, like game controllers.</p>
<p>I’ve implemented a system so I can use WASD-keys and/or arrow keys for movement, touch buttons on mobile, and even
through game controllers (a Nintendo switch controller which I could connect through an Xbox controller plugin on
windows).</p>
<figure class="image">
<img title="Touch buttons that will rotate the cubes, move the player and allows us to move back to the main menu" src="/images/kuubed/image17.png" width="800" />
<figcaption>Touch buttons that will rotate the cubes, move the player and allows us to move back to the main menu</figcaption>
</figure>
<p>You will see the buttons on mobile/touch screen enabled systems, and they disappear on non-touch platforms. Since my laptop has a touchscreen as well, I needed to add an option in the menu to hide the touch bars :)</p>
<p><br />
<br /></p>
<h1 id="cube-sides">Cube sides</h1>
<p>Meanwhile, the editor could save levels into a JSON format, and the level scene could load the JSON, so we have a full
working game in essence :)</p>
<p>Since the main idea would be to have a playfield inside a cube, I still wanted to have a cube experience (on some levels).
So it’s possible to tell that we want to see a cube in our level-data JSON (actually, you can control each of the six sides).</p>
<table class="img_table">
<tr><td>
<figure class="image">
<img title="Complete transparent wall when facing the player" src="/images/kuubed/image18.png" width="400" />
<figcaption>Complete transparent wall when facing the player</figcaption>
</figure>
</td><td>
<figure class="image">
<img title="Having a bit of transparent wall in front of the player as well" src="/images/kuubed/image19.png" width="400" />
<figcaption>Having a bit of transparent wall in front of the player as well</figcaption>
</figure>
</td></tr>
</table>
<p>It turns out that I couldn’t find any nice-looking cube sides. So it took a while to find some. Ultimately, I settled on a grid-like texture, which happens to scale nicely with the blocks inside the cube.</p>
<p><br />
<br /></p>
<h1 id="portals">Portals</h1>
<p>One idea I had was the use of portals. Not only can you rotate the cube to move to seemingly impossible positions, but with the help of portals, you can transport yourself to another part of the cube. This took a long time to finish, much
longer than expected for a couple of reasons:</p>
<p>I wanted to have some ‘stargate’ block, where you walk into and come out of another block. This turned
out to be a bit hard to do, so I settled on a ‘pool’ in the ground. Transporting the astronaut to the right other side isn’t hard, but the positioning was since the portal can be rotated another way. Not only was the astronaut’s rotation hard, but there are times we need to rotate the cube automatically to make sure
the astronaut will ALWAYS turn up “upwards.”</p>
<p>It took some work in redesigning the level-data JSON (elements needed not only a position but also a direction) and took a lot of
vector calculations which took a while to get right.</p>
<p>Another thing that took a while was creating the actual portal pool. For this, I used shader-graph and with the help of some
tutorials, I got started with drag and dropping some shaders until I found something that looked nice enough.</p>
<figure class="image">
<img title="Drag and dropping a shader" src="/images/kuubed/image21.png" width="800" />
<figcaption>Drag and dropping a shader</figcaption>
</figure>
<figure class="image">
<img title="Initial portals with differnt colors per portal" src="/images/kuubed/image24.png" width="800" />
<figcaption>Initial portals with differnt colors per portal</figcaption>
</figure>
<figure class="image">
<img title="Or just white portals" src="/images/kuubed/image25.png" width="800" />
<figcaption>Or just white portals</figcaption>
</figure>
<figure class="image">
<img title="In our metal theme, the portals actually 'fall' inside the block nicely" src="/images/kuubed/image22.png" width="800" />
<figcaption>In our metal theme, the portals actually 'fall' inside the block nicely</figcaption>
</figure>
<figure class="image">
<img title="Added some lights to the portals" src="/images/kuubed/image23.png" width="800" />
<figcaption>Added some lights to the portals</figcaption>
</figure>
<figure class="image">
<img title="Testing portals on different blocks. The left one looks the best" src="/images/kuubed/image26.png" width="800" />
<figcaption>Testing portals on different blocks. The left one looks the best</figcaption>
</figure>
<p><br />
<br /></p>
<h1 id="themes">Themes</h1>
<p>Since pretty much the beginning of game development, I’ve opted for a theme-like system, so blocks, backgrounds, etc., could all be
changed dynamically. I bought a pack containing all kinds of low-poly cubes from the Unity Asset store and implemented
some themes.</p>
<p>Some look better than others, and I’m still not 100% convinced if we should do themes, but they are there in case I want to implement
them in the final game.</p>
<p>Some designs:</p>
<table class="img_table">
<tr>
<td><img title="" src="/images/kuubed/image30.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image31.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image32.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image42.png" alt="" width="200" /></td>
</tr>
</table>
<table class="img_table">
<tr>
<td><img title="" src="/images/kuubed/image43.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image35.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image36.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image37.png" alt="" width="200" /></td>
</tr>
</table>
<table class="img_table">
<tr>
<td><img title="" src="/images/kuubed/image38.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image39.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image40.png" alt="" width="200" /></td>
<td><img title="" src="/images/kuubed/image41.png" alt="" width="200" /></td>
</tr>
</table>
<p><br />
<br /></p>
<h1 id="ads--analytics">Ads & Analytics</h1>
<p>I wanted to have some analytics in the game to see what’s going on in the field once the game will be released. Unity makes this easy, and I got it up and running in no time.</p>
<p>I only target a few key points in the game:
When a level starts.
When a player dies (and how).
When a level completes (and the time it took).
This gives me a way to indicate how hard levels are, when players are quitting, etc.</p>
<p>Even though I’m not too fond of ads, I understand they are needed to get some income. So I opted for two ways to do this:
have a free version of the game, containing ads, and a pro-version, paid, but with no ads and more levels.</p>
<p>The ads are displayed when a level starts, and there is a 33% chance that an ad is displayed when a player dies. This is to make sure people can continue their game without getting annoyed by ads all the time. I don’t know if this is an excellent way to do it, but I can constantly adjust the ratios if needed.</p>
<p>During debugging, I earned my first 2 cents :p</p>
<figure class="image">
<img title="Show me the monies!" src="/images/kuubed/image44.png" width="400" />
<figcaption>Show me the monies!</figcaption>
</figure>
<p>It’s nice to see that Unity makes these things simple to implement. There are a lot of settings that can be tweaked which I do not know anything about it. But I have to assume the default settings are ok enough.</p>
<p><br />
<br /></p>
<h1 id="release">Release</h1>
<p>Although we are almost done, many things still need to be taken care of. More levels have to be created, and tests should be done (maybe hire somebody from Fiverr for this again?). Get more feedback from people to tell me what can/needs
to be improved.</p>
<p>I’m not a game developer. I stink when it comes to design, frontend, and an Indie developer I will never become, I’m afraid. But it’s nice to do something different than coding web APIs once in a while.</p>
2021-09-01T00:00:00-05:00https://adayinthelifeof.nl/2021/03/04/go-map-vs-switch.htmlGo maps vs switches2021-03-04T00:00:00-06:00Joshua Thijssenjthijssen@noxlogic.nl<p>Sometimes, things aren’t faster because you think it is,.. but because you benchmarked them. One of Go’s nice things is that it makes it easy to benchmark things to see if your hunches are correct quickly. And sometimes, they turn out not.</p>
<!--more-->
<h1 id="switch-vs-maps">Switch vs. maps</h1>
<p>Once in a while, I need to map a string, int, or another type to something else. This usually turns out to become a switch statement where I map each element to something else. It works fine for a small number of elements, but a large list of case statements isn’t very readable as soon as you have a lot. It also increases your gocyclo complexity.</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"> <span class="k">var</span> <span class="n">message</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">status</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="m">200</span><span class="o">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">"ok"</span>
<span class="k">case</span> <span class="m">404</span><span class="o">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">"not found"</span>
<span class="c">// insert a lot of extra elements</span>
<span class="p">}</span></code></pre></figure>
<p>So I tend to use maps instead. That way, I have a small amount of code plus a readable map that doesn’t suffer for readability:</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"> <span class="k">var</span> <span class="n">httpCodes</span> <span class="k">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
<span class="m">200</span><span class="o">:</span> <span class="s">"ok"</span><span class="p">,</span>
<span class="m">404</span><span class="o">:</span> <span class="s">"not found"</span><span class="p">,</span>
<span class="c">// much cleaner</span>
<span class="p">}</span>
<span class="n">message</span><span class="p">,</span> <span class="n">ok</span> <span class="o">:=</span> <span class="n">httpCodes</span><span class="p">[</span><span class="n">status</span><span class="p">]</span>
<span class="k">if</span> <span class="o">!</span><span class="n">ok</span> <span class="p">{</span>
<span class="c">// maybe set something default or return error</span>
<span class="p">}</span> </code></pre></figure>
<p>Since both are lookup tables, you would expect both to be pretty similar in performance. Or at least, so I thought. Let’s see what
happens when we do a benchmark on both:</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">"testing"</span>
<span class="p">)</span>
<span class="k">var</span> <span class="n">httpStatus</span> <span class="o">=</span> <span class="k">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
<span class="m">200</span><span class="o">:</span> <span class="s">"ok"</span><span class="p">,</span>
<span class="m">404</span><span class="o">:</span> <span class="s">"not found"</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">var</span> <span class="n">result</span> <span class="o">=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">string</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">func</span> <span class="n">doMap</span><span class="p">(</span><span class="n">code</span> <span class="kt">int</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span>
<span class="n">status</span><span class="p">,</span> <span class="n">ok</span> <span class="o">:=</span> <span class="n">httpStatus</span><span class="p">[</span><span class="n">code</span><span class="p">]</span>
<span class="k">if</span> <span class="o">!</span><span class="n">ok</span> <span class="p">{</span>
<span class="n">status</span> <span class="o">=</span> <span class="s">""</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">status</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">doSwitch</span><span class="p">(</span><span class="n">code</span> <span class="kt">int</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span>
<span class="k">var</span> <span class="n">message</span> <span class="o">=</span> <span class="s">""</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">code</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="m">200</span><span class="o">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">"ok"</span>
<span class="k">case</span> <span class="m">404</span><span class="o">:</span>
<span class="n">message</span> <span class="o">=</span> <span class="s">"not found"</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">message</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">BenchmarkSwitch</span><span class="p">(</span><span class="n">b</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">B</span><span class="p">)</span> <span class="p">{</span>
<span class="n">r</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">string</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">for</span> <span class="n">n</span><span class="o">:=</span><span class="m">0</span><span class="p">;</span> <span class="n">n</span><span class="o"><</span><span class="n">b</span><span class="o">.</span><span class="n">N</span><span class="p">;</span> <span class="n">n</span><span class="o">++</span> <span class="p">{</span>
<span class="n">r</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="m">200</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="m">404</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="m">999</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">r</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">BenchmarkMap</span><span class="p">(</span><span class="n">b</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">B</span><span class="p">)</span> <span class="p">{</span>
<span class="n">r</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">string</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">for</span> <span class="n">n</span><span class="o">:=</span><span class="m">0</span><span class="p">;</span> <span class="n">n</span><span class="o"><</span><span class="n">b</span><span class="o">.</span><span class="n">N</span><span class="p">;</span> <span class="n">n</span><span class="o">++</span> <span class="p">{</span>
<span class="n">r</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="m">200</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="m">404</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="m">999</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">r</span>
<span class="p">}</span></code></pre></figure>
<p>Running it with <code class="language-plaintext highlighter-rouge">go test --bench=.</code> gives us the following result:</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text"> $ go test --bench=.
goos: linux
goarch: amd64
BenchmarkSwitch-12 808913143 1.47 ns/op
BenchmarkMap-12 80380466 14.5 ns/op
PASS</code></pre></figure>
<blockquote>
<p>There was an issue that it seems that Go had optimized the whole testing code out, resulting in a way too low ns/op. I’ve added some additional code that should not optimize the functionality we want to test out.</p>
</blockquote>
<p>It seems that the map lookup is almost 10 times slower (still fast, though). I’ve compiled the code to assembly to figure out what’s going on. It seems that the switch is fast because it is not directly a jump-table (as I expected), but a linked list (is the code 200, no goto next check etc).</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text"> 0x0000 00000 (map_test.go:26) MOVQ "".code+8(SP), AX
0x0005 00005 (map_test.go:26) CMPQ AX, $200
0x000b 00011 (map_test.go:26) JNE 36
0x000d 00013 (map_test.go:26) PCDATA $0, $1
0x000d 00013 (map_test.go:26) LEAQ go.string."ok"(SB), AX
0x0014 00020 (map_test.go:26) MOVL $2, CX
0x0019 00025 (map_test.go:32) PCDATA $0, $0
0x0019 00025 (map_test.go:32) PCDATA $1, $1
0x0019 00025 (map_test.go:32) MOVQ AX, "".~r1+16(SP)
0x001e 00030 (map_test.go:32) MOVQ CX, "".~r1+24(SP)
0x0023 00035 (map_test.go:32) RET
0x0024 00036 (map_test.go:28) PCDATA $1, $0
0x0024 00036 (map_test.go:28) CMPQ AX, $404
0x002a 00042 (map_test.go:28) JNE 58
0x002c 00044 (map_test.go:28) PCDATA $0, $1
0x002c 00044 (map_test.go:28) LEAQ go.string."not found"(SB), AX
0x0033 00051 (map_test.go:28) MOVL $9, CX
0x0038 00056 (map_test.go:25) JMP 25
0x003a 00058 (map_test.go:25) XORL AX, AX
0x003c 00060 (map_test.go:25) XORL CX, CX
0x003e 00062 (map_test.go:25) JMP 25</code></pre></figure>
<p>However, the map takes a lot more time. This is probably because it calls <code class="language-plaintext highlighter-rouge">runtime.mapaccess2_fast64(SB)</code>, which might still be a fast access call, but it is still a call and compared to a simple compare in the switch code quite slow.</p>
<h2 id="mapping-from-string-to-int">Mapping from string to int</h2>
<p>So let’s turn things around: instead of mapping ints to strings. Let’s map the string to an int instead.</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="p">(</span>
<span class="s">"testing"</span>
<span class="p">)</span>
<span class="k">var</span> <span class="n">httpStatus</span> <span class="o">=</span> <span class="k">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span>
<span class="s">"ok"</span><span class="o">:</span> <span class="m">200</span><span class="p">,</span>
<span class="s">"not found"</span><span class="o">:</span> <span class="m">404</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">doMap</span><span class="p">(</span><span class="n">message</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">int</span> <span class="p">{</span>
<span class="n">code</span><span class="p">,</span> <span class="n">ok</span> <span class="o">:=</span> <span class="n">httpStatus</span><span class="p">[</span><span class="n">message</span><span class="p">]</span>
<span class="k">if</span> <span class="o">!</span><span class="n">ok</span> <span class="p">{</span>
<span class="n">code</span> <span class="o">=</span> <span class="m">0</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">code</span>
<span class="p">}</span>
<span class="k">var</span> <span class="n">result</span> <span class="o">=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">func</span> <span class="n">doSwitch</span><span class="p">(</span><span class="n">message</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">int</span> <span class="p">{</span>
<span class="k">var</span> <span class="n">code</span> <span class="kt">int</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">message</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="s">"ok"</span><span class="o">:</span>
<span class="n">code</span> <span class="o">=</span> <span class="m">200</span>
<span class="k">case</span> <span class="s">"not found"</span><span class="o">:</span>
<span class="n">code</span> <span class="o">=</span> <span class="m">404</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">code</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">BenchmarkSwitch</span><span class="p">(</span><span class="n">b</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">B</span><span class="p">)</span> <span class="p">{</span>
<span class="n">r</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">for</span> <span class="n">n</span><span class="o">:=</span><span class="m">0</span><span class="p">;</span> <span class="n">n</span><span class="o"><</span><span class="n">b</span><span class="o">.</span><span class="n">N</span><span class="p">;</span> <span class="n">n</span><span class="o">++</span> <span class="p">{</span>
<span class="n">r</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="s">"ok"</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="s">"not found"</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">doSwitch</span><span class="p">(</span><span class="s">"not implemented"</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">r</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">BenchmarkMap</span><span class="p">(</span><span class="n">b</span> <span class="o">*</span><span class="n">testing</span><span class="o">.</span><span class="n">B</span><span class="p">)</span> <span class="p">{</span>
<span class="n">r</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
<span class="k">for</span> <span class="n">n</span><span class="o">:=</span><span class="m">0</span><span class="p">;</span> <span class="n">n</span><span class="o"><</span><span class="n">b</span><span class="o">.</span><span class="n">N</span><span class="p">;</span> <span class="n">n</span><span class="o">++</span> <span class="p">{</span>
<span class="n">r</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="s">"ok"</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="s">"not found"</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="m">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">doMap</span><span class="p">(</span><span class="s">"not implemented"</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">r</span>
<span class="p">}</span></code></pre></figure>
<p>And the result:</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text"> goos: linux
goarch: amd64
BenchmarkSwitch-12 697366684 1.67 ns/op
BenchmarkMap-12 100000000 11.4 ns/op
PASS
ok command-line-arguments 2.498s</code></pre></figure>
<p>It seems that both functions perform pretty much the same.</p>
<p>When compiled to assembler, we see that the map functionality compiles into pretty much identical code, except now we have
a call to <code class="language-plaintext highlighter-rouge">runtime.mapaccess2_faststr</code>. The switch statement has changed too. Instead of comparing simple ints, it first
checks the length of a given string against the length of the string we match (so in the first case, it checks if the
length of <code class="language-plaintext highlighter-rouge">message</code> is 2). If this isn’t equal, there is no point in checking the rest of the string, but if it does match,
it will continuously load 8 bytes of string and compare it against the message (8 bytes, since that what can fit in the 64-bit
register). Still, it’s a fast process because of the fast-failures in the system.</p>
<h2 id="so-which-one-should-we-be-using">So which one should we be using?</h2>
<p>So it looks like the switch wins, but it seems to have a<code class="language-plaintext highlighter-rouge">O(N)</code> complexity because of the iteration overall cases, while the map has an <code class="language-plaintext highlighter-rouge">O(1)</code> complexity. It doesn’t necessarily mean that the map is better than the switch, since we need to consider the number of elements (it takes a while before the O(1) is faster), and of course, readability is an issue. It depends on the situation what you would use, and in some cases, I will go for the maps, and other cases for the switch. But if speed is your concern, benchmark your stuff!</p>
2021-03-04T00:00:00-06:00https://adayinthelifeof.nl/2020/08/12/mac2win.htmlFrom Mac to Windows2020-08-12T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>I’ve moved from a Macbook Pro to a Dell PS running Windows 10. I decided against MacBook after their annoucement to
move to ARM. Even though the macbook 16” was the only system i actually was thinking of buying, i’ve decided against it
and give windows a new try. I’ve heared more and more good stories about windows, and more and more bad stored about mac
over the last few years. Let’s switch!</p>
<!--more-->
<h1 id="from-mac-to-win">from mac to win</h1>
<p>I moved from a MacBookPro early 2011 (yes, really) to a Dell XPS 9700. I did a <code class="language-plaintext highlighter-rouge">#treatyouself</code>
and added a Dell uw4919dw monitor to it as well. So the machine is pretty much the top of what we can buy these days.
I’ve got the 17”, which in fact is just a few mm larger than my MBP 15(.4)” and it’s lighter (it’s still heavy, but i’m
used to lugging around a brick for almost 10 years). So more screen estate (4 times actually!) on the laptop alone.</p>
<p>Windows first laughed at me when booted up, because of 16GB memory. But that was easily fixed by moving to 64GB (you
hear that Apple, user replaceable stuff!). Since then, i’ve got a RAM usage of about 20-30GB with most of it used in
vmmain (WSL2/docker stuff which is capped to 16GB so no worries there).</p>
<p>I really like the machine itself. There is a completely useless touchscreen on there but I didn’t go for the “larger”
videocard as I don’t play games. Saves some battery time as well.</p>
<p>The whole everything-is-a-usb-C thing wasn’t so bad as I expected. There is a small dongle for hdmi/usb-a which I use at
home for connecting a mouse. But at the office I do everything from a single USB-C cable instead of plugging in 3 cables
on my mac. So power, DP signal, usb-hubs etc are all connected through a single cable. Mouse and keyboard being
bluetooth.</p>
<h1 id="about-windows">About windows</h1>
<p>On the OS side of things: it’s pretty acceptable to work with. I did some tryouts with a windows machine before and felt
I could get along on windows 10. WSL2 is really neat. I can finally do docker things right again although it’s a bit
trail and error to get things setup the right way. (docker, phpstorm, xdebug, golang all want their own way of doing
things, which can be tricky).</p>
<p>I can’t get used to the taskbar, so I replaced it with Nexus Winstep and got a nice OSX look&feel. It’s not quite the
same dock as a mac, but close enough. Even systray icons are neatly stacked in the bar. In fact, I like it better than
mac’s docker system by now.</p>
<p>The only thing that doesn’t really work well is the fact that the icons are not animated in the sense of displaying a
button when new mail or slack messages have arrived. It also doesn’t provide the same context menu, where I could click
on phpstorm, and open a recent project. One more thing to unlearn I guess.</p>
<p>I’ve also installed Wox, which gives me spotlight which works well enough. I could use the win-key, but somehow it
doesn’t feel right for me. It still gives me way to many results (powered by “everything.exe”, which I still need to
tweak I guess).</p>
<p>Most applications that I use are available on windows as well, so i don’t have to relearn/miss much. There is a thing
to be said on Paw (HTTP test system), but i heard on twitter there might be something coming up very soon. Oh joy!</p>
<p>I’m actually quite surprised by Windows Terminal. It’s got enough features to make it workable. Especially since the
fact I’m using panes a lot and you can do a lot of nice things with them in Terminal (except moving them to another
part of the screen, something i did a lot).</p>
<p>Windows PowerShell is utter crap and hope it dies a horrible death. I can’t understand how anyone in their right mind
actually likes that system. Cmd.exe is still the useless program like it was 15 years ago.</p>
<p>I also miss a “sudo”, as I tried to run chocolaty things. I’ve got a quick link to an elevated shell so I can do a
choco install and get out as quickly as possible. Seems workable enough but now my system is actually installed, i
don’t need it as much.</p>
<p>Backup is also a thing. I tried things with onedrive, only to get all my stuff removed and moved “into the cloud”. I
hate when that happens, so i disabled the whole onecloud stuff (thanks, i have enough clouds already). Since i do some
backups on backblaze already, I’m actually using their system to do a continuous backup. It’s not quite timemachine,
but good enough (i hope). I realize that loosing my computer means a complete reinstall of windows anyway, so again:
nothing changed there in the last 15 years.</p>
<p>As said: WSL is really nice.. it’s like Linux, but just not quite. Which is annoying when you want to do things like
setting up dbus, gpg etc.. I’m also trying to figure out how to get ssh correctly running on both wsl and windows so I
can use the same keys in my ssh-agent (provided that works under windows, still not sure).</p>
<p>Also another thing: I got completely chrome-less (well not quite, as I still use chromium for electronjs stuff), but no
chrome browser installed. I use firefox which is actually quite nice, and I’ve got edge, which is what I downloaded
firefox with.</p>
<h2 id="a-few-annoying-things">A few annoying things</h2>
<p>There are some things that bug me though:</p>
<ul>
<li>my soundcard driver sometimes crashes after a sleep. It happens a few times now but no real cause can be found. A
restart usually works. I tried to call microsoft “support” to see if they knew a solution. Like i thought:
“abishek” (like there are 500 million of them in India i guess), just followed his script and told me the only thing
to do is update drivers, restart your machine and hope for the best.. so again: nothing has changed in the last 15
years there neither. I actually called Dell support (Leroy) which was more helpful and could help me. We did some
updates and issues seem to have gone away. My fingerprint scanner didn’t work anymore, and my system kept rebooting
automatically once in a while, but that’s the price you pay for updates I guess. Luckily this seemed to be fixed
with more updates from Leroy. System seems stable now. These are the things Apple got right: one single system means
much more reliable driver configurations (well, in theory).</li>
<li>firefox has a nasty thing that it cannot parse console pages on AWS. I get xml errors but a refresh helps. Annoying
and it’s probably due to a plugin I guess? It’s not annoying enough to actually dive into it.</li>
</ul>
<h2 id="happy-or-not">Happy or not?</h2>
<p>So.. Am I happy with the move? Well.. I’m not unhappy. That probably says a lot coming from a default pessimistic guy.
I still miss my macbook, but the struggle against a new keyboard layout, ctrl/alt switcheroos and such are less and
less. I think I can get used to this system. And the screen real-estate I have nowadays… oh my!</p>
2020-08-12T00:00:00-05:00https://adayinthelifeof.nl/2020/06/12/bitmaelum.htmlIntroducting BitMaelum - A new mail concept2020-06-12T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>What if you can design an email system with a clean sheet. You don’t need to care about existing email clients or servers or anything at all. Even the concept of an email address can be touched. What would such a system look like? This is my attempt,..</p>
<!--more-->
<figure>
<img title="BitMaelum" src="/images/logo_and_name.svg" width="400" alt="logo" />
</figure>
<h2 id="attempted-by-many-failed-by-even-more">Attempted by many, failed by even more</h2>
<p>I know. Here’s some random guy trying to change the way that the whole world uses to communicate. Let’s be realistic: there is no way email gets replaced because it works well for companies and works well for anybody else too.
Sure, we have to give up privacy in most cases, but we get back a relatively spam-free inbox at Google or any of the
(handful) providers currently left hosting email.</p>
<p>But email has evolved on top of a system that wasn’t designed for today’s problems. We solved this by adding layers on top of layers to make sure everybody plays nicely, and still, it doesn’t work as well as it should be. No wonder that nobody wants to host their email anymore (I do, by the way), because even if you configure your mail server, DKIM, SPF,
DMarc and other things correctly, it’s all still a crapshoot.</p>
<p>What happens if Google gets into a grumpy mood and decides your Gmail gets blocked, frozen, or deleted? Can you cope with the fact that nobody can reach you, or you can’t reach your account? Don’t like Google anymore? Well, good luck setting
up a new account somewhere else and making sure all your accounts on the internet use that address.</p>
<p>We try to solve many problems, and lots of right solutions exist. But all rely on the fact that we use the same
underlying infrastructure as designed in the ’80s.</p>
<p>So let’s rm-rf everything and try again. Will it work? Probably not. There are so many things I didn’t think about, and
oh boy, don’t get me started on crypto.</p>
<p>But it’s a fun pet-project to play with: design a system that should theoretically run on a massive scale in a
decentralized way. How can we achieve a system that is secure and respects privacy when we know for a fact that there are hostile systems out there. How do we make sure sending spam is not economical anymore, yet we still allow for legitimate email listings (how do we even define “legitimate”?).</p>
<h2 id="introducing-bitmaelum">Introducing BitMaelum</h2>
<p>So, my version of the story is called BitMaelum. I’ve tried to think of the (many) problems current email systems
currently face and try to come up with a system that solves many of those problems without introducing (too many)
others.</p>
<p>Among other things, it tries to solve the following problems:</p>
<ul>
<li>
<p>Get rid of domain names. We only need them for routing and namespacing. Instead, have names/handles that are generic and can be suffixed with an organization if you want. But nobody should care that your grandma hosts her email at
gmail.com.</p>
</li>
<li>
<p>Pick-up your account and go. You’re not bound to a single email server or domain anymore. Don’t like it, move to somebody else (or start your own) mail server. Your address stays the same.</p>
</li>
<li>
<p>A guarantee that the sender was A) the real sender, and B) the message hasn’t been tampered with.</p>
</li>
<li>
<p>End to end encryption. There is no way for mail servers or any organization snooping in between to read your email.
Even metadata is encrypted. The only thing visible for mail servers is routing info (which is hashed as well, so, by default, we don’t even know to where we send a message to). Only the receiver can read the message locally. Not even the hosting mail server can read the message.</p>
</li>
<li>
<p>Mail servers can ask for proof-of-work before accepting mails. We can leverage this system to ask for more work for
large spam runs economically infeasible.</p>
</li>
<li>
<p>A user and only the user can be added to a mailing-list. Not on the mailing-list: you need proof-of-work.
Sending a 24.000 user mailing list might take 24 hours that way, or even longer, while legitimate enlisted users get their messages directly.</p>
<p>It should take more time and computational effort to send 1000 spam mails than to send 1.000.000 legitimate emails.</p>
</li>
<li>
<p>Want to subscribe? You are in charge, and it doesn’t take 5 to 7 business days to process your subscription.
When unsubscribed, the mail server either refuses the email, or asks proof-of-work.</p>
</li>
</ul>
<h2 id="1-2-3-go">1 2 3, Go</h2>
<p>I dabble a bit in Go. Not fulltime, unfortunately, but enough to create tooling and small apps. I decided to write this system in Go because we could get one single binary to run your mail server. Also, cross-compilation to other platforms should be easy enough.</p>
<h2 id="so-many-problems-so-little-time">So many problems, so little time</h2>
<p>So there are many things to think about. How do we deal with organizations? How to deal with search? Can we search your
email on a mobile device, or should we download the message first (server-search?). What if we lose our key (there is no “forgot password” option).</p>
<p>Anyway, there is a lot to figure out, and currently, I’m trying to put my ideas on paper (wiki) and write proof-of-concept code. It’s messy, and it’s ugly, it’s hard, it will never work, but I love it!</p>
<p>You can find the experimental code on github: <a href="https://github.com/bitmaelum">https://github.com/bitmaelum</a></p>
<p>Oh.. and if you have a BitMaelum server running, do send me a message on <code class="language-plaintext highlighter-rouge">jaytaph!</code> :-)</p>
2020-06-12T00:00:00-05:00https://adayinthelifeof.nl/2020/05/20/aws.htmlAmazon Web Services2020-05-20T00:00:00-05:00Joshua Thijssenjthijssen@noxlogic.nl<p>More often than not, I’m using Amazon Web Services (AWS) as my “cloud”. Not only for my own projects, but almost all customers I’m working for use Amazon for hosting their applications. So over time you build up a lot of experience on AWS service: you know how to (correctly) setup VPC’s, know when to you ECS, EC2 or lambda to host code and even services like S3, SNS and SQS pose no challenges anymore.</p>
<p>But there are a lot of AWS services available. And I do mean: a LOT. Currently, there are 163 (!) different services that are available from the Amazon Dashboard, each with their own way of working, difficulties, catches and best practises.</p>
<!--more-->
<h2 id="discovering-aws">Discovering AWS</h2>
<p>You might realise that it’s probably near impossible to dive into each service and completely understand how they work and most likely, you don’t really need to know the exact ins and outs. But, having a basic understanding on each service can be a major benefit as a developer, architect or administrator. It makes it easier to see if there is an already existing solution for your
problem at hand.</p>
<p>So, I dove into each and every service to figure out what it exactly was for and how it works in the basics. I tried to experiment with as many components as possible (time and money permitting, I didn’t want to spend 15.000$ on AWS Data Exchange). I tried to capture what the service does in a single one-liner to give you a global overview.</p>
<p>I think most of them are correct enough but if you have any suggestions or corrections, please tell me!</p>
<table class="aws_tables">
<thead>
<tr>
<th><strong>Compute</strong></th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>EC2</td>
<td>Virtual Private Servers</td>
</tr>
<tr>
<td>Lightsail</td>
<td>Amazon’s hosting provider (vps, dns, storage)</td>
</tr>
<tr>
<td>Lambda</td>
<td>Functions you can run, written in Python, NodeJS, Go etc. Can run many in parallel.</td>
</tr>
<tr>
<td>Batch</td>
<td>Run software jobs in Docker containers on EC2 machines</td>
</tr>
<tr>
<td>Elastic Beanstalk</td>
<td>Run software on managed virtual machines</td>
</tr>
<tr>
<td>Serverless Application Repository</td>
<td>Repository of serverless applications that you can deploy (on lambda)</td>
</tr>
<tr>
<td>AWS Outposts</td>
<td>Run Amazon services in your own data center</td>
</tr>
<tr>
<td>EC2 Image Builder</td>
<td>Create EC2 (ami?) images automatically</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th><strong>Storage</strong></th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>S3</td>
<td>File / object storage. Not primarily used for mounting as filesystem, but you can directly download files through HTTP.</td>
</tr>
<tr>
<td>EFS</td>
<td>NFS. Mount network disks to your machines.</td>
</tr>
<tr>
<td>FSx</td>
<td>Windows / Lustre filesystems you can connect to your ec2 machines</td>
</tr>
<tr>
<td>S3 Glacier</td>
<td>Low cost storage system for backups and archives and such</td>
</tr>
<tr>
<td>Storage Gateway</td>
<td>iSCSI so you can connect s3 to your own (remote) machine.</td>
</tr>
<tr>
<td>AWS Backup</td>
<td>Automatically create backups of different AWS service (ec2, rds etc)</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Database</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>RDS</td>
<td>Managed mysql, postgres databases etc.</td>
</tr>
<tr>
<td>DynamoDB</td>
<td>Large & scalable non-relational database</td>
</tr>
<tr>
<td>ElastiCache</td>
<td>Managed memcache and redis machines</td>
</tr>
<tr>
<td>Neptune</td>
<td>Graph database</td>
</tr>
<tr>
<td>Amazon Redshift</td>
<td>Warehousing. Store lots of data that can be processed through streams.</td>
</tr>
<tr>
<td>Amazon QLDB</td>
<td>Database for immutable and cryptographically verifiable data (money transactions etc)</td>
</tr>
<tr>
<td>Amazon DocumentDB</td>
<td>MongoDB clone (but not really compatible anymore)</td>
</tr>
<tr>
<td>Amazon Keyspaces</td>
<td>Managed Apache Cassandra clone</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Migration & Transfer</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AS Migration Hub</td>
<td>Migrate things from your DC to AWS</td>
</tr>
<tr>
<td>Application Discovery Service</td>
<td>Discover services in your datacenter</td>
</tr>
<tr>
<td>Database Migration Service</td>
<td>Migrate databases to RDS while staying online (can convert structures as well)</td>
</tr>
<tr>
<td>Server Migration Service</td>
<td>Migrate virtual machines to amazon.</td>
</tr>
<tr>
<td>AWS Transfer Family</td>
<td>(s)FTP service with S3 backend. Upload to FTP, directly store on S3 bucket.</td>
</tr>
<tr>
<td>Snowball</td>
<td>Get a machine from AWS, plug in your DC, transfer data fast to AWS, return machine</td>
</tr>
<tr>
<td>DataSync</td>
<td>Sync data between your datacenter and AWS</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Networking & Content Delivery</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC</td>
<td>Create your own virtual private network within AWS.</td>
</tr>
<tr>
<td>CloudFront</td>
<td>Content Delivery Network.</td>
</tr>
<tr>
<td>Route 53</td>
<td>Manage domain names and records.</td>
</tr>
<tr>
<td>API Gateway</td>
<td>Create HTTP APIs and let them connect to different backends.</td>
</tr>
<tr>
<td>Direct Connect</td>
<td>Create a (physical) connection between you (or DC) to AWS.</td>
</tr>
<tr>
<td>AWS App Mesh</td>
<td>Automatically run Envoy as a sidecar for your containers (ECS or EKS).</td>
</tr>
<tr>
<td>AWS Cloud Map</td>
<td>Service discovery for your containers.</td>
</tr>
<tr>
<td>Global Accelerator</td>
<td>Run your app on edge locations so they are closer to your customers (CDN for apps).</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Developer Tools</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>CodeStar</td>
<td>Quickly develop applications by using template code and codecommit, codebuild etc</td>
</tr>
<tr>
<td>CodeCommit</td>
<td>Amazon source repositories (git repo’s etc)</td>
</tr>
<tr>
<td>CodeBuild</td>
<td>CI service</td>
</tr>
<tr>
<td>CodeDeploy</td>
<td>Deployment service</td>
</tr>
<tr>
<td>CodePipeline</td>
<td>Code delivery with workflows</td>
</tr>
<tr>
<td>Cloud9</td>
<td>Online IDE</td>
</tr>
<tr>
<td>X-Ray</td>
<td>Allows tracing in your applications, supports Python, NodeJs, Go etc.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Robotics</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS RoboMaker</td>
<td>Cloud solution for robotic developers to simulate, test and securely deploy robotic applications</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Customer Enablement</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS IQ</td>
<td>Job board: Hire AWS experts for whatever you need.</td>
</tr>
<tr>
<td>Support</td>
<td>AWS support center</td>
</tr>
<tr>
<td>Managed Services</td>
<td>Let AWS handle your AWS services for you.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Blockchain</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon Managed Blockchain</td>
<td>Block chains</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Satellite</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Ground Station</td>
<td>Timeshare radios and large antennas pointed at space</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Quantum Technologies</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon Braket</td>
<td>Some quantum thing. It’s in preview so I have no idea what it is.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Management & Governance</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS Organizations</td>
<td>Configure (sub)organisations and accounts</td>
</tr>
<tr>
<td>CloudWatch</td>
<td>Logging from various AWS components</td>
</tr>
<tr>
<td>AWS Auto Scaling</td>
<td>Scale resources based on your custom inputs and rules</td>
</tr>
<tr>
<td>CloudFormation</td>
<td>Templates to create and configure AWS components (think terraform/sls)</td>
</tr>
<tr>
<td>CloudTrail</td>
<td>Figure out who did what in your AWS services</td>
</tr>
<tr>
<td>Config</td>
<td>Audit the configurations of your AWS resources</td>
</tr>
<tr>
<td>OpsWorks</td>
<td>Use Ansible to automate stuff</td>
</tr>
<tr>
<td>Service Catalog</td>
<td>Manage list of items/codes etc you have in the cloud</td>
</tr>
<tr>
<td>Systems Manager</td>
<td>View data from your resources grouped in ways you like (like application specific etc)</td>
</tr>
<tr>
<td>AWS AppConfig</td>
<td>Store and publish application configuration data</td>
</tr>
<tr>
<td>Trusted Advisor</td>
<td>Checks your account for issues (costs, performance, security etc)</td>
</tr>
<tr>
<td>Control Tower</td>
<td>Manage multi-accounts</td>
</tr>
<tr>
<td>AWS License Manager</td>
<td>Manage licenses</td>
</tr>
<tr>
<td>AWS Well-Architected Tool</td>
<td>Generate questionnaires about your architecture to see if you follow best practices</td>
</tr>
<tr>
<td>Personal Health Dashboard</td>
<td>StatusPage for AWS</td>
</tr>
<tr>
<td>AWS Chatbot</td>
<td>Connect AWS to slack</td>
</tr>
<tr>
<td>Launch Wizard</td>
<td>Deploy MSSQL or SAP</td>
</tr>
<tr>
<td>AWS Compute Optimizer</td>
<td>Finds your resources and advices on how to save costs</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Media Services</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Elastic Transcoder</td>
<td>Encode files from S3 into different other formats and store back at S3</td>
</tr>
<tr>
<td>Kinesis Video Streams</td>
<td>Capture media streams</td>
</tr>
<tr>
<td>MediaConnect</td>
<td>?</td>
</tr>
<tr>
<td>MediaConvert</td>
<td>Convert media into different formats</td>
</tr>
<tr>
<td>MediaLive</td>
<td>Share live video with many others</td>
</tr>
<tr>
<td>MediaPackage</td>
<td>?</td>
</tr>
<tr>
<td>MediaStore</td>
<td>?</td>
</tr>
<tr>
<td>MediaTailor</td>
<td>Insert advertisements into your broadcasts</td>
</tr>
<tr>
<td>Elemental Appliances & Software</td>
<td>create videos on-premise. Basically a mix of all of the above services. Seems expensive. Probably is.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Machine Learning</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon SageMaker</td>
<td>Machine learning tools</td>
</tr>
<tr>
<td>Amazon CodeGuru</td>
<td>Profile java code with machine learning</td>
</tr>
<tr>
<td>Amazon Comprehend</td>
<td>Understand and classify data like emails, tweets etc</td>
</tr>
<tr>
<td>Amazon Forecast</td>
<td>Create forecasts from data</td>
</tr>
<tr>
<td>Amazon Fraud Detector</td>
<td>in preview so no idea.</td>
</tr>
<tr>
<td>Amazon Kendra</td>
<td>Search service where you can ask questions</td>
</tr>
<tr>
<td>Amazon Lex</td>
<td>Create voice and chatbots</td>
</tr>
<tr>
<td>Amazon Machine Learning</td>
<td>Deprecated. Use SageMaker instead.</td>
</tr>
<tr>
<td>Amazon Personalize</td>
<td>Create personalized recommendations based on data (mahout??)</td>
</tr>
<tr>
<td>Amazon Polly</td>
<td>Convert text to speech in different languages</td>
</tr>
<tr>
<td>Amazon Rekognition</td>
<td>Recognize objects and people in images</td>
</tr>
<tr>
<td>Amazon Textract</td>
<td>Convert text found in images to text (OCR)</td>
</tr>
<tr>
<td>Amazon Transcribe</td>
<td>Convert audio to text</td>
</tr>
<tr>
<td>Amazon Translate</td>
<td>Translates text from one language to another</td>
</tr>
<tr>
<td>AWS DeepLens</td>
<td>A video camera that does machine learning</td>
</tr>
<tr>
<td>AWS DeepRacer</td>
<td>Some kind of game where you program a racecar to race against others.</td>
</tr>
<tr>
<td>Amazon Augmented AI</td>
<td>Let humans in the loop to make AI learn things better</td>
</tr>
<tr>
<td>AWS DeepComposer</td>
<td>Computer generated music. It’s as horrible as it sounds.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Analytics</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Athena</td>
<td>Query data stored in s3 buckets.</td>
</tr>
<tr>
<td>EMR</td>
<td>Elastic Map/Reduce</td>
</tr>
<tr>
<td>CloudSearch</td>
<td>AWS version of managed document search system (like elasticsearch)</td>
</tr>
<tr>
<td>Elasticsearch Service</td>
<td>Elasticsearch as a service</td>
</tr>
<tr>
<td>Kinesis</td>
<td>Collect massive amount of data so you can do analytics (like ELK?)</td>
</tr>
<tr>
<td>QuickSight</td>
<td>Business Intelligence service</td>
</tr>
<tr>
<td>Data Pipeline</td>
<td>Move and transform data to dynamodb, rds, s3 etc.</td>
</tr>
<tr>
<td>AWS Data Exchange</td>
<td>Find APIs which data you can consume, which can be very expensive</td>
</tr>
<tr>
<td>AWS Glue</td>
<td>ETL service. Enrich, validate data.</td>
</tr>
<tr>
<td>AWS Lake Formation</td>
<td>Create data lakes</td>
</tr>
<tr>
<td>MSK</td>
<td>Kafka as a service</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Security, Identity, & Compliance</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>IAM</td>
<td>AWS’s permission system that can control users and AWS services.</td>
</tr>
<tr>
<td>Resource Access Manager</td>
<td>Share certain AWS resources like Route53, licenses, ec2 with other accounts.</td>
</tr>
<tr>
<td>Cognito</td>
<td>User and password management system. Useful for managing users for your applications.</td>
</tr>
<tr>
<td>Secrets Manager</td>
<td>Secrets key/value store. Can automatically rotate secrets.</td>
</tr>
<tr>
<td>GuardDuty</td>
<td>Automatically scan your cloudtrail/vpc logs for threats.</td>
</tr>
<tr>
<td>Inspector</td>
<td>Automatically find (security) issues in your network and machines.</td>
</tr>
<tr>
<td>Amazon Macie</td>
<td>Analyzes data in your S3 buckets and check for PII data.</td>
</tr>
<tr>
<td>AWS Single Sign-On</td>
<td>Allow single-sign on to your applications.</td>
</tr>
<tr>
<td>Certificate Manager</td>
<td>Manage and even create (free) SSL certificates.</td>
</tr>
<tr>
<td>Key Management Service</td>
<td>Manage secret keys</td>
</tr>
<tr>
<td>CloudHSM</td>
<td>Hardware security modules. Allows you to generate and operate on cryptographic keys.</td>
</tr>
<tr>
<td>Directory Service</td>
<td>Active directory as a service</td>
</tr>
<tr>
<td>WAF & Shield</td>
<td>Web Application Firewall (for loadbalancers, cloudfront, api gateway). Can setup your own rules or use predefined ones</td>
</tr>
<tr>
<td>AWS Firewall Manager</td>
<td>Firewall manager for different accounts in your organisation</td>
</tr>
<tr>
<td>Artifact</td>
<td>Documents for cloud compliance (things like 27001 certification etc)</td>
</tr>
<tr>
<td>Security Hub</td>
<td>Overall security checker that uses guardduty, inspector, macie etc</td>
</tr>
<tr>
<td>Detective</td>
<td>Log security issues found (from security hub etc)</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Mobile</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS Amplify</td>
<td>Let AWS automatically generate frontend & backend apps and deploy them automatically.</td>
</tr>
<tr>
<td>Mobile Hub</td>
<td>Part of AWS Amplify now.</td>
</tr>
<tr>
<td>AWS AppSync</td>
<td>Create API backends that you can connect to. Can be created through AWS Amplify as well.</td>
</tr>
<tr>
<td>Device Farm</td>
<td>AWS BrowserStack. Automatically test apps on many different mobile devices and browsers.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>AR & VR</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon Sumerian</td>
<td>3D Editor and Engine for rapidly prototyping AR/VR and 3D experiences</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Application Integration</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Step Functions</td>
<td>State machines written in amazon’s own language</td>
</tr>
<tr>
<td>Amazon AppFlow</td>
<td>Automatically connects apps together (zapier?). For instance: slack to s3 buckets.</td>
</tr>
<tr>
<td>Amazon EventBridge</td>
<td>Some kind of eventbus system</td>
</tr>
<tr>
<td>Amazon MQ</td>
<td>ActiveMQ</td>
</tr>
<tr>
<td>Simple Notification Service</td>
<td>Notification system that can notify through email, api endpoints, sms etc.</td>
</tr>
<tr>
<td>Simple Queue Service</td>
<td>Message queue system</td>
</tr>
<tr>
<td>SWF</td>
<td>Create workflows.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>AWS Cost Management</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS Cost Explorer</td>
<td>Gives an overview and projection of your budgets</td>
</tr>
<tr>
<td>AWS Budgets</td>
<td>Create budgets for your AWS components</td>
</tr>
<tr>
<td>AWS Marketplace Subscriptions</td>
<td>Find (and buy) AMI’s with software installed</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Customer Engagement</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon Connect</td>
<td>AWS call center platform</td>
</tr>
<tr>
<td>Pinpoint</td>
<td>Create transactional emails, SMS or voice calls based on templates.</td>
</tr>
<tr>
<td>Simple Email Service</td>
<td>Send out emails. Email provider.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Business Applications</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Alexa for Business</td>
<td>Connect Alexa to your business needs.</td>
</tr>
<tr>
<td>Amazon Chime</td>
<td>AWS version of Zoom.</td>
</tr>
<tr>
<td>WorkMail</td>
<td>AWS version of Gmail / Calendar.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>End User Computing</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>WorkSpaces</td>
<td>Virtual desktops from Windows or Linux.</td>
</tr>
<tr>
<td>AppStream 2.0</td>
<td>Stream applications running native onto your browser</td>
</tr>
<tr>
<td>WorkDocs</td>
<td>Store your documents and manage them online.</td>
</tr>
<tr>
<td>WorkLink</td>
<td>Connect mobile users to your intranet.</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Internet Of Things</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>IoT Core</td>
<td>Manage fleets of IOT devices through MQTT broker</td>
</tr>
<tr>
<td>FreeRTOS</td>
<td>RTOS operating system for microcontrollers to automatically connect to IOT-Core or greengrass.</td>
</tr>
<tr>
<td>IoT 1-Click</td>
<td>Manage 1-click buttons that can be connected to other systems like Lambda</td>
</tr>
<tr>
<td>IoT Analytics</td>
<td>Clean up and save messages from topics into a data-store for analytics</td>
</tr>
<tr>
<td>IoT Device Defender</td>
<td>Detect unwanted issues on your devices and take actions</td>
</tr>
<tr>
<td>IoT Device Management</td>
<td>Organize IoT devices into groups, schedule jobs on the devices and configure remote access</td>
</tr>
<tr>
<td>IoT Events</td>
<td>Monitor telemetry from devices and then trigger other AWS services or jobs on the devices themselves</td>
</tr>
<tr>
<td>IoT Greengrass</td>
<td>A message broker can buffer messages for groups of up to 200 devices which can communicate and process data locally if connectivity to IoT Core is intermittent.</td>
</tr>
<tr>
<td>IoT SiteWise</td>
<td>Collect, organize, analyze and visualize data from industrial equipment at scale</td>
</tr>
<tr>
<td>IoT Things Graph</td>
<td>Cloudformation-like designer for graphing how devices should communicate with other AWS services</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Game Development</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon GameLift</td>
<td>Deploy game servers with low latency on AWS</td>
</tr>
</tbody>
</table>
<table class="aws_tables">
<thead>
<tr>
<th>Containers</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>Elastic Container Registry</td>
<td>Store docker images like on DockerHub</td>
</tr>
<tr>
<td>Elastic Container Service</td>
<td>Run containers, either on your own EC2 machines, or on managed machines called Fargate.</td>
</tr>
<tr>
<td>Elastic Kubernetes Service</td>
<td>Kubernetes as a service</td>
</tr>
</tbody>
</table>
<p>Thanks to Brian Thomas Smith for filling in the blanks on IoT.
Thanks to all the others from #HN who suggested changes and updates on the different services.</p>
<h1 id="conclusion">Conclusion</h1>
<p>With over 150 services running on Amazon AWS, it’s near impossible to be an expert on all of them. And that’s ok: when you deal with large EKS or ECS clusters, changes are you never will touch the IOT services for instances. I found that most services are pretty well explained and easy to start with.</p>
<p>One of the biggest issues are the IOT services: since I have no experience with smart devices, MQTT or IOT in general, i finally managed to get a simple GO application to connect to IOT-core, and connect different rules, pipelines, analytics etc to it. But even still it’s very unclear what the different services actually do. Hopefully there will be AWS IOT experts out there that can
enlighten me.</p>
2020-05-20T00:00:00-05:00