{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "NNBlog",
  "language": "en",
  "home_page_url": "https://nnb.codeberg.page/blog",
  "feed_url": "https://nnb.codeberg.page/blog/en/feed.xml",
  "description": "Blog that SuperB",
  "author": {
    "name": "NNB",
    "url": "https://nnb.codeberg.page"
  },
  "items": [
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/19/",
      "url": "https://nnb.codeberg.page/blog/en/posts/19/",
      "title": "The Glodot is real!",
      "content_html": "<h2 id=\"what\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#what\" aria-hidden=\"true\">#</a> What?</h2>\n<p><strong>Glodot</strong> == <a href=\"https://godotengine.org/\">Godot</a> + <a href=\"https://gleam.run/\">Gleam</a>. It's a way to run Gleam code inside Godot.</p>\n<h2 id=\"who\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#who\" aria-hidden=\"true\">#</a> Who?</h2>\n<p><em>&quot;Who discover this?&quot;</em> - Me!</p>\n<p><em>&quot;Glodot is for whom?&quot;</em> - It's for people who like <a href=\"https://en.wikipedia.org/wiki/Functional_programming\">FP (Functional programming)</a> and want to use it for gamedev.</p>\n<h2 id=\"when-where\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#when-where\" aria-hidden=\"true\">#</a> When/where?</h2>\n<p>Glodot is ideal for <a href=\"https://en.wikipedia.org/wiki/Business_logic\">the domain logic</a> (like writing complex algorithms). Even for simple stuff like handling result from swipe gestures in a <a href=\"https://play2048.co/\">2048 game</a>, writing in Gleam is way more breathable compared to GDScript.</p>\n<p>However, it's hard to interacts directly outside of domain logic from the Gleam code (like interacts heavily with the node tree and handling physics for exmaple)...</p>\n<h2 id=\"why\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#why\" aria-hidden=\"true\">#</a> Why?</h2>\n<p>Godot is a great game engine but GDscript is not a good language to do domain logic stuffs. And yes, C# is better but not as good as a real FP langauge.</p>\n<p>Gleam is the savior that fill the gap in the Godot ecosystem. Its syntax is beautiful, modern, familiar, easy to read, to manage and to learn (can be learn in a day). Plus Gleam's tooling is convenient, more than its of Lua, Python, C#...</p>\n<p>Therefore, this is the perfect combination:</p>\n<ul>\n<li>GDscript for convenient &quot;real world&quot; interactions and handle physic.</li>\n<li>Gleam for writing domain logic functions with predefined input and output, like complex algorithms/calculations.</li>\n</ul>\n<h2 id=\"how\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#how\" aria-hidden=\"true\">#</a> How?</h2>\n<p>The road to connect from Godot to Gleam is as follows:</p>\n<ul>\n<li><strong><a href=\"https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_basics.html\">Godot Mono</a>:</strong> To use C# in Godot.</li>\n<li><strong><a href=\"https://github.com/Microsoft/ClearScript\">ClearScript</a>:</strong> <a href=\"https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_basics.html#using-nuget-packages-in-godot\"><em>Use that NuGet package in Godot</em></a> to run Javascript code in C#.</li>\n<li><strong><a href=\"https://bun.sh/\">Bun</a> or any JS bundler:</strong> To bundler Javascript code to one single <code>.js</code> file.</li>\n<li><strong><a href=\"https://gleam.run/command-line-reference\">Gleam compiler</a>:</strong> To compiler all the epic codes you write.</li>\n</ul>\n<p>Your Glodot files structure should look like this:</p>\n<pre><code>.  (Root of Godot project)\n├── core  (Root of Gleam package)\n│   ├── gleam.toml\n│   ├── manifest.toml\n│   ├── package.json\n│   ├── src\n│   │   └── core\n│   │       ├── core.gleam  (The file that contains all functions to be accessible from outside Gleam)\n│   │       └── ...\n├── project.godot\n├── project.csproj\n├── core.txt  (Bundled Gleam-to-JS code)\n├── core.gd  (Util to execute bundled code in Godot)\n└── V8.cs  (Util to execute JS code in Godot)\n</code></pre>\n<h3 id=\"gleam-side\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#gleam-side\" aria-hidden=\"true\">#</a> Gleam side</h3>\n<p>First create a Gleam package inside your Godot project's root:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">gleam new core <span class=\"token comment\"># It's could be named anything.</span></code></pre>\n<p>Then write your domain logic stuffs here. When you done, make a signle file that contains all functions to be accessible from outside of Gleam (name it <code>core.gleam</code>):</p>\n<pre class=\"language-rust\"><code class=\"language-rust\">import core<span class=\"token operator\">/</span>a_stuffs\nimport core<span class=\"token operator\">/</span>b_stuffs\n\n<span class=\"token keyword\">pub</span> <span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">fn_a</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">-></span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n  a_stuffs<span class=\"token punctuation\">.</span><span class=\"token function\">fn_a</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">pub</span> <span class=\"token keyword\">fn</span> <span class=\"token function-definition function\">fn_b</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">-></span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n  b_stuffs<span class=\"token punctuation\">.</span><span class=\"token function\">fn_b</span><span class=\"token punctuation\">(</span>input<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// ...</span></code></pre>\n<p>⚠️ WARNING! BIG WARNING! You cannot use custom Gleam type as input/output outside of Gleam, at least it's not behaved as you thinks. You can only use <code>Int</code>, <code>Float</code> and <code>String</code>. Even <code>List</code> and <code>Dict</code> is not the same as JS's Array and Object. The best solution is to warp input and output as JSON string.</p>\n<p>So after you write you fancy code in a Gleam package for your game, make sure to set the target to JS in the <code>gleam.toml</code> config file:</p>\n<pre class=\"language-diff\"><code class=\"language-diff\"><span class=\"token unchanged\"><span class=\"token prefix unchanged\"> </span> name = \"core\"\n<span class=\"token prefix unchanged\"> </span> version = \"1.0.0\"\n</span><span class=\"token inserted-sign inserted\"><span class=\"token prefix inserted\">+</span> target = \"javascript\"\n</span>\n...</code></pre>\n<p>Then bundler the JS codes after each time you compiler:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token builtin class-name\">cd</span> ./core\nbun build ./build/dev/javascript/core/core/core.mjs <span class=\"token parameter variable\">--outfile</span> <span class=\"token punctuation\">..</span>/core.txt</code></pre>\n<p>Yep it's end with <code>.txt</code> so that Godot can detect and read the texts inside that file.</p>\n<p>And remember to remove the <code>export</code> part inside the bundled file so that V8 don't warning.</p>\n<h3 id=\"godot-side\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#godot-side\" aria-hidden=\"true\">#</a> Godot side</h3>\n<p>First install <a href=\"https://github.com/Microsoft/ClearScript\">ClearScript</a> to your system:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">nuget <span class=\"token function\">install</span> Microsoft.ClearScript.Complete</code></pre>\n<p>Then add it to the <code>project.csproj</code> file:</p>\n<pre class=\"language-diff\"><code class=\"language-diff\"><span class=\"token unchanged\"><span class=\"token prefix unchanged\"> </span> &lt;Project Sdk=\"Godot.NET.Sdk/4.4.1\">\n<span class=\"token prefix unchanged\"> </span>   &lt;PropertyGroup>\n<span class=\"token prefix unchanged\"> </span>     &lt;TargetFramework>net8.0&lt;/TargetFramework>\n<span class=\"token prefix unchanged\"> </span>     &lt;EnableDynamicLoading>true&lt;/EnableDynamicLoading>\n<span class=\"token prefix unchanged\"> </span>     &lt;RootNamespace>project&lt;/RootNamespace>\n<span class=\"token prefix unchanged\"> </span>   &lt;/PropertyGroup>\n</span><span class=\"token inserted-sign inserted\"><span class=\"token prefix inserted\">+</span>   &lt;ItemGroup>\n<span class=\"token prefix inserted\">+</span>     &lt;PackageReference Include=\"Microsoft.ClearScript.Complete\" Version=\"7.5.0\" />\n<span class=\"token prefix inserted\">+</span>   &lt;/ItemGroup>\n</span><span class=\"token unchanged\"><span class=\"token prefix unchanged\"> </span> &lt;/Project>\n</span></code></pre>\n<p>Write an util name <code>V8.cs</code> in your project to execute JS code:</p>\n<pre class=\"language-cs\"><code class=\"language-cs\"><span class=\"token keyword\">using</span> <span class=\"token namespace\">Godot</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">System</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">Microsoft<span class=\"token punctuation\">.</span>ClearScript<span class=\"token punctuation\">.</span>V8</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">partial</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">V8</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">Node</span></span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token class-name\">V8ScriptEngine</span> _engine <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token constructor-invocation class-name\">V8ScriptEngine</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token return-type class-name\"><span class=\"token keyword\">string</span></span> <span class=\"token function\">eval</span><span class=\"token punctuation\">(</span><span class=\"token class-name\"><span class=\"token keyword\">string</span></span> code<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> Convert<span class=\"token punctuation\">.</span><span class=\"token function\">ToString</span><span class=\"token punctuation\">(</span>_engine<span class=\"token punctuation\">.</span><span class=\"token function\">Evaluate</span><span class=\"token punctuation\">(</span>code<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>Finally, make an util to execute Gleam-to-JS bundled code (name it <code>core.gd</code>):</p>\n<pre class=\"language-gdscript\"><code class=\"language-gdscript\"><span class=\"token keyword\">extends</span> <span class=\"token class-name\">Node</span>\n\n<span class=\"token keyword\">const</span> _v8 <span class=\"token operator\">:=</span> <span class=\"token keyword\">preload</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"res://src/V8.cs\"</span><span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">func</span> <span class=\"token function\">_ready</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">void</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">var</span> core_file <span class=\"token operator\">:=</span> FileAccess<span class=\"token punctuation\">.</span><span class=\"token function\">open</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token string\">\"res://core.txt\"</span><span class=\"token punctuation\">,</span> FileAccess<span class=\"token punctuation\">.</span><span class=\"token constant\">READ</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">var</span> core_code <span class=\"token operator\">:=</span> core_file<span class=\"token punctuation\">.</span><span class=\"token function\">get_as_text</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    _v8<span class=\"token punctuation\">.</span><span class=\"token function\">eval</span><span class=\"token punctuation\">(</span>core_code<span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">func</span> <span class=\"token function\">fn_a</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">:</span>\n\t<span class=\"token keyword\">return</span> <span class=\"token function\">_invoke</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token string\">\"fn_a\"</span><span class=\"token punctuation\">,</span> arg<span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">func</span> <span class=\"token function\">fn_b</span><span class=\"token punctuation\">(</span>arg<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">:</span>\n\t<span class=\"token keyword\">return</span> <span class=\"token function\">_invoke</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span><span class=\"token string\">\"fn_b\"</span><span class=\"token punctuation\">,</span> arg<span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">func</span> <span class=\"token function\">_invoke</span><span class=\"token punctuation\">(</span>funcName<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> argument<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">Variant</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">var</span> code<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Variant</span> <span class=\"token operator\">=</span> <span class=\"token operator\">&amp;</span><span class=\"token string\">\"{funcName}(\\\"{argument}\\\")\"</span><span class=\"token punctuation\">.</span><span class=\"token function\">format</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        <span class=\"token operator\">&amp;</span><span class=\"token string\">\"funcName\"</span><span class=\"token punctuation\">:</span> funcName<span class=\"token punctuation\">,</span>\n        <span class=\"token operator\">&amp;</span><span class=\"token string\">\"argument\"</span><span class=\"token punctuation\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span>argument<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json_escape</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">var</span> result<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Variant</span> <span class=\"token operator\">=</span> _v8<span class=\"token punctuation\">.</span><span class=\"token function\">eval</span><span class=\"token punctuation\">(</span>code<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">var</span> json <span class=\"token operator\">:=</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">new</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">var</span> error <span class=\"token operator\">:=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">parse</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">if</span> error<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> result <span class=\"token operator\">!=</span> <span class=\"token operator\">&amp;</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">:</span>\n            <span class=\"token function\">printerr</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">null</span>\n\n    <span class=\"token keyword\">return</span> json<span class=\"token punctuation\">.</span>data</code></pre>\n<h3 id=\"export-to-web\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#export-to-web\" aria-hidden=\"true\">#</a> Export to web</h3>\n<p>As said in <a href=\"https://docs.godotengine.org/en/4.4/tutorials/export/exporting_for_web.html\">the Godot document</a>:</p>\n<blockquote>\n<p>Projects written in C# using Godot 4 currently cannot be exported to the web. See <a href=\"https://godotengine.org/article/platform-state-in-csharp-for-godot-4-2/#web\">this blog post</a> for more information.</p>\n</blockquote>\n<p>However you can fallback to use <a href=\"https://docs.godotengine.org/en/stable/tutorials/platform/web/javascript_bridge.html#doc-web-javascript-bridge\"><code>JavaScriptBridge</code></a> to run JS code instate of C# + ClearScript when export to web.</p>\n<h3 id=\"additional\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#additional\" aria-hidden=\"true\">#</a> Additional</h3>\n<p>Here are some Gleam libraries that are useful for gamedev:</p>\n<ul>\n<li><a href=\"https://hexdocs.pm/gleam_community_maths\"><code>gleam_community_maths</code></a>: A basic mathematics library that contains some of the most fundamental mathematics functions and utilities.</li>\n<li><a href=\"https://hexdocs.pm/prng\"><code>prng</code></a>: A lib to handle PRNG (Pure Random Number Generator).</li>\n<li><a href=\"https://hexdocs.pm/vec\"><code>vec</code></a>: A vector library, has almost everything that can be done in Godot.</li>\n<li><a href=\"https://hexdocs.pm/vec_dict\"><code>vec_dict</code></a>: This is to represent and handle a 2D, 3D  and even 4D grid.</li>\n</ul>\n<h3 id=\"alternatives-route\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/19/#alternatives-route\" aria-hidden=\"true\">#</a> Alternatives route?</h3>\n<p>The Godot Mono - ClearScript route mentioned above seems quite roundabout, but it's currently the most &quot;official&quot; way. Godot Mono is an official version of Godot, and ClearScript is a library from Microsoft (the creator of C#), make this approach quite stable.</p>\n<p>Glodot <em><strong>could</strong></em> potentially be made by using <a href=\"https://godotjs.github.io/\">GodotJS</a> to replace the route above, connecting Godot to compiled Gleam code purely through JS/TS.</p>\n<p>But that is a shortcut, because at the time of writing, GodotJS is quite buggy/janky. I hope it will improve soon, because if GodotJS becomes as stable and easy to set up as Godot Mono, it would be an ideal method.</p>\n<p>But if I could wish, I want a Godot plugin that could automatically compile a specified Gleam package and then provide an API to easily run it.</p>\n<p><em>Well that's all fork, stay gleamy~!</em></p>\n",
      "date_published": "2025-07-19T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/18/",
      "url": "https://nnb.codeberg.page/blog/en/posts/18/",
      "title": "Convenient IRB methods",
      "content_html": "<p>Below are a bunch of snippets to add to your <a href=\"https://docs.ruby-lang.org/en/master/IRB.html#module-IRB-label-Configuration+File\">IRB config</a> for convenient scripting / personal use. But don't put this directly into any codebase, that will be a bad practice.</p>\n<h2 id=\"set-xor\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/18/#set-xor\" aria-hidden=\"true\">#</a> Set XOR</h2>\n<pre class=\"language-rb\"><code class=\"language-rb\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Array</span>\n  <span class=\"token comment\"># Returns the union of `array` and Array `other` minus elements in both.</span>\n  <span class=\"token keyword\">def</span> <span class=\"token operator\">^</span><span class=\"token punctuation\">(</span>other<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">self</span> <span class=\"token operator\">|</span> other<span class=\"token punctuation\">)</span> <span class=\"token operator\">-</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">self</span> <span class=\"token operator\">&amp;</span> other<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">end</span>\n<span class=\"token keyword\">end</span></code></pre>\n<h2 id=\"random\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/18/#random\" aria-hidden=\"true\">#</a> Random</h2>\n<pre class=\"language-rb\"><code class=\"language-rb\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Random</span>\n  <span class=\"token comment\"># Return a random boolean value.</span>\n  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span><span class=\"token function\">bool</span></span>\n    <span class=\"token punctuation\">[</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>sample\n  <span class=\"token keyword\">end</span>\n\n  <span class=\"token comment\"># Returns a random string containing `size` characters from `characters`.</span>\n  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span><span class=\"token function\">string</span></span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">,</span> characters <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'a'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'z'</span></span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'A'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'Z'</span></span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'0'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'9'</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token class-name\">Array</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> characters<span class=\"token punctuation\">.</span>sample <span class=\"token punctuation\">}</span><span class=\"token punctuation\">.</span>join\n  <span class=\"token keyword\">end</span>\n\n  <span class=\"token comment\"># Return a random boolean value.</span>\n  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token function\">bool</span></span>\n    <span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span>rand<span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>zero<span class=\"token operator\">?</span>\n  <span class=\"token keyword\">end</span>\n\n  <span class=\"token comment\"># Returns a random string containing `size` characters from `characters`.</span>\n  <span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token function\">string</span></span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">,</span> characters <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'a'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'z'</span></span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'A'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'Z'</span></span><span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span><span class=\"token string-literal\"><span class=\"token string\">'0'</span></span><span class=\"token operator\">..</span><span class=\"token string-literal\"><span class=\"token string\">'9'</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token class-name\">Array</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">new</span><span class=\"token punctuation\">(</span>size<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> characters<span class=\"token punctuation\">[</span><span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span>rand<span class=\"token punctuation\">(</span>characters<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">.</span>join\n  <span class=\"token keyword\">end</span>\n<span class=\"token keyword\">end</span></code></pre>\n<p><em>If you want to securely generate random strings, check out <a href=\"https://rubyapi.org/o/securerandom\"><code>SecureRandom</code></a>.</em></p>\n<h2 id=\"clear\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/18/#clear\" aria-hidden=\"true\">#</a> Clear</h2>\n<pre class=\"language-rb\"><code class=\"language-rb\"><span class=\"token comment\"># Clear the terminal.</span>\n<span class=\"token keyword\">def</span> <span class=\"token method-definition\"><span class=\"token function\">clear</span></span>\n  print <span class=\"token string-literal\"><span class=\"token string\">\"\\033c\"</span></span>\n<span class=\"token keyword\">end</span></code></pre>\n<h2 id=\"null-stream\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/18/#null-stream\" aria-hidden=\"true\">#</a> Null stream</h2>\n<pre class=\"language-rb\"><code class=\"language-rb\"><span class=\"token variable\">$null</span> <span class=\"token operator\">=</span> <span class=\"token builtin\">File</span><span class=\"token punctuation\">.</span>open<span class=\"token punctuation\">(</span><span class=\"token builtin\">File</span><span class=\"token double-colon punctuation\">::</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span> <span class=\"token string-literal\"><span class=\"token string\">'w'</span></span><span class=\"token punctuation\">)</span></code></pre>\n<p>&lt;3</p>\n",
      "date_published": "2024-02-11T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/17/",
      "url": "https://nnb.codeberg.page/blog/en/posts/17/",
      "title": "Stop Linux from freezing",
      "content_html": "<h2 id=\"story\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/17/#story\" aria-hidden=\"true\">#</a> Story</h2>\n<p>Since I first switched to Linux, my computer always freezes every time I do heavy work. At the beginning, it froze a few times a month. When the laptop froze, I have to turn it off, no different from when I used Windows. Then its became more and more frequent, to the point that my computer froze almost daily. After researching, I found that my computer seems to freeze every time the RAM is nearly or completely full. My laptop have 2GB of RAM, I tried adding a 4GB swap partition, but it doesn't seem help. &quot;Maybe it's because my laptop is so old&quot; I thought to myself.</p>\n<p>I got a better laptop when I go to college. With 8GB of RAM, the condition no longer occurs daily, but its frequency is still every week... Quite annoying, I can't open a lot of tabs on the web browser because I fear that will cause freezing. When I want to play 3D heavy game, I have to turn off every thing else. Et cetera...</p>\n<p>I saved up money from competitions prizes, and finally bought a laptop myself! The device still has 8GB of ram, but the CPU and GPU are much more powerful. The condition was improved... It freezes about 2-3 time a month. There are times when I often play heavy games, and it quickly freezes every week...</p>\n<p>Things really got worse when I switched to <a href=\"https://blendos.co/\">BlendOS</a>, it freezes almost every day, for the first week I installed Blend. I quickly checked the system monitor, and realized that: For some reason BlendOS doesn't have swap!</p>\n<h2 id=\"solution\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/17/#solution\" aria-hidden=\"true\">#</a> Solution</h2>\n<p>I decided to add a swap, this time I gave it 16GB just to be sure:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">btrfs filesystem mkswapfile <span class=\"token parameter variable\">--size</span> 16G ~/.cache/swapfile\n<span class=\"token function\">sudo</span> <span class=\"token function\">swapon</span> ~/.cache/swapfile</code></pre>\n<p>Then add this to <code>/etc/fstab</code>:</p>\n<pre><code>/var/home/USERNAME/.cache/swapfile\tswap    swap    defaults 0 0\n</code></pre>\n<p>Since then, my PC never freezes ever again, like a dream come true! Now I can open more than 20 browser tabs with game and heavy application, all at the same time. In the past, I had to use my laptop carefully because I was afraid it would freeze, Now I can freely open as many applications as I want!</p>\n<p>The lesson here is: If Linux often freezes due to full RAM, try increase swap, <strong>lot of swap</strong>! It seems like I almost solved the problem a while ago when I tried increasing the swap a bit, If I tried to increase it more, I might not have to upgrade my laptop~</p>\n",
      "date_published": "2024-02-10T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/16/",
      "url": "https://nnb.codeberg.page/blog/en/posts/16/",
      "title": "Debunking allegations about Flappy Bird",
      "content_html": "<p>A decade ago, at the end of 2013, the world witnessed the rise of Flappy Bird - a mobile game with simple design yet a high skill ceiling, piquing the desire to overcome challenges in many players. Thanks to that, Flappy Bird became a worldwide phenomenon and trend at the start of 2014. However, not long after, on the same date as today (February 8th) 10 years ago, Nguyen Ha Dong - the father of Flappy Bird - couldn't handle the overwhelming negative public opinion anymore, and took the billion-dollar game off all app stores.</p>\n<p>This historic event, despite happening 10 years ago, still left many suspicions and misunderstandings in many people's memories. Today, I want to deny some false allegations that were made towards Flappy Bird.</p>\n<p>Before that, I want to thank SoullessPuppet for helping me check and translate this entire article into English. Thank you and happy holiday!</p>\n<h2 id=\"disclaimer\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#disclaimer\" aria-hidden=\"true\">#</a> Disclaimer</h2>\n<p>No one is completely free of bias, nor perfectly neutral. I, myself, am a Vietnamese, and also an aspiring game developer, so I have a lot of sympathy towards Mr. Dong. I just want to clarify that, although I try to be as fair as possible, I still have a bias towards Flappy Bird. But the points I will make do come with evidence.</p>\n<p>PLEASE DO NOT HARASS ANY INDIVIDUAL OR ORGANIZATION MENTIONED IN THIS POST !!!!!</p>\n<p>I know there will inevitably be some readers who feel the need to punish those who victimized Mr. Dong. But I'm asking every reader not to do so. Harassment is the same thing the media and internet did to the man, and we should not stoop so low. Moreover, it has been 10 years, so we should let the past stay in the past. Those who made mistakes 10 years ago are likely very different people today.</p>\n<h2 id=\"allegation-1-used-bots\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#allegation-1-used-bots\" aria-hidden=\"true\">#</a> Allegation 1: Used bots</h2>\n<h3 id=\"smoke-and-mirrors\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#smoke-and-mirrors\" aria-hidden=\"true\">#</a> &quot;Smoke &amp; Mirrors&quot;</h3>\n<p>Most news articles point to <a href=\"https://web.archive.org/web/20140204181721/http://www.bluecloudsolutions.com/blog/flappy-birds-smoke-mirrors-scamming-app-store\">&quot;Flappy Bird's Smoke &amp; Mirrors - Is Something Fishy Going On?&quot;</a> (on Bluecloud) as the source when mentioning this allegation.</p>\n<p>The argument presented by the post is as follows: Games that DotGears released during mid 2013 all became popular during November of the same year - roughly the same time. Yet there were no cross-advertisements in the games, nor were there any marketing campaigns ran at the time.</p>\n<p><em>Quoted from <a href=\"https://www.thechocolatelabapps.com/how-to-make-flappy-bird\">An interview with Dong on Chocolate Lab Apps</a>:</em></p>\n<blockquote>\n<p><strong>Elaine:</strong> Is your success due to organic downloads only, or did you use any other methods?</p>\n<p><strong>Dong:</strong> I didn’t use any promotion methods. All accounts on Twitter, Facebook and Instagram about Flappy Bird are not mine. The popularity could be my luck.</p>\n</blockquote>\n<p>These arguments may sound suspicious, but if DotGears used bots to inflate their numbers, then wouldn't it be super obvious? Apple would have intervened and deleted it from the platform. During the 2012-2013 period, botting was a prevalent issue on the App Store, and <a href=\"https://www.pocketgamer.com/news/apple-offers-official-warning-to-app-store-manipulators\">Apple worked on resolving this problem</a> to <a href=\"https://www.pocketgamer.com/research/app-store-download-volumes-still-to-bounce-back-from-bot-farm-ban\">some success</a>. Apple and Google would have taken some actions, if an extremely trendy game often accused of cheating was actually cheating.</p>\n<p>The official twitter account of the App Store even <a href=\"https://twitter.com/AppStore/status/431537791642918912\">made a post about Flappy Bird</a>:</p>\n<blockquote>\n<p>We got to 99. What's your high score?</p>\n</blockquote>\n<p>The &quot;Smoke &amp; Mirrors&quot; article then provided some evidence to back up their argument: There were some suspicious reviews...:</p>\n<blockquote>\n<p>Here’s another nice little tidbit. Read through the reviews. Check the word count. Do an analysis on how many times the word &quot;glitch&quot; &quot;pipe&quot; &quot;addicting&quot; are used relative to the review length. Also check how many negative reviews give 5 stars.</p>\n<p>Here’s a quick snapshot from a 3 minute scroll through Flappy Bird’s reviews.</p>\n<p><img src=\"https://web.archive.org/web/20140204122641im_/http://www.bluecloudsolutions.com/wp-content/uploads/2014/01/reviews.jpg\" alt=\"The reviews\" /></p>\n<p>I don’t think there is any app on the app store that has this many consistently morbid reviews that use the same words over and over and are posted in such regularity.</p>\n</blockquote>\n<p>On the image provided by the article are 9 reviews. The term &quot;addicting&quot; appeared twice, &quot;pipe&quot; appeared once and &quot;glitch&quot; never appeared... All 9 reviews are very different and had no signs of being copy-pasted. I'm not sure if the author is being ironic or not? These reviews are less like bots reviews and more like an example of <a href=\"https://en.wikipedia.org/wiki/Groupthink\">groupthink</a>, more specifically, a joke where everyone pretend they are a victim of this frustrating game. Almost everyone was in on the joke, except the author.</p>\n<p>In a data research, the author of <a href=\"http://zachwill.com/flappy-bird\">&quot;Flappy Bird by the Numbers&quot; bởi Zachwill</a> concluded:</p>\n<blockquote>\n<p>I was originally planning to focus on the December/January Flappy Bird reviews — I thought it’d be fun to prove that they were most likely bots. After loading the reviews into <a href=\"http://pandas.pydata.org/\"><code>pandas</code></a> and playing around with the data, though, it became pretty clear those had little to nothing to do with the success of Flappy Bird.</p>\n</blockquote>\n<h3 id=\"it-doesn-t-matter\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#it-doesn-t-matter\" aria-hidden=\"true\">#</a> &quot;It doesn't matter&quot;</h3>\n<p>In the article <a href=\"https://www.newsweek.com/flappy-bird-cooking-its-itunes-rank-228016\">&quot;Is Flappy Bird Cooking its iTunes Rank?&quot;</a> posted on February 4th on Newsweek, an article putting Flappy Bird's ranking into question, <a href=\"https://twitter.com/joekloc/status/430755599437938688\">Reporter Joe Kloc asked Dong on Twitter about the legitimacy of Flappy Bird's download count</a>:</p>\n<blockquote>\n<p><strong>Joe Kloc:</strong> @dongatory Hello. I'm a reporter at Newsweek. Is there an email address through would I could contact you directly about Flappy Bird?</p>\n<p><strong>Dong:</strong> @joekloc Hi Joe, I think press should give my game some peace. Its success is really overrate! I'm sorry, I refuse to answer questions.</p>\n<p><strong>Joe Kloc:</strong> @dongatory I'm just curious about the post going around saying the download stats are false. Can you definitively say they aren't?</p>\n<p><strong>Dong:</strong> @joekloc It doesn't matter. Don't you think? If I did fake it, should Apple let it live for months?</p>\n<p><strong>Joe Kloc:</strong> @dongatory If it doesn't matter, did you?</p>\n</blockquote>\n<p>Dong's line &quot;It doesn't matter&quot; implied that it didn't matter what his answer to the bots question was, because the press and the internet community are going to find a way to hate on him regardless. The question asked by the reporter was a <a href=\"https://en.wikipedia.org/wiki/Double_bind\">double bind</a>:</p>\n<ol>\n<li>If he denied the allegations, people would say that he's a liar.</li>\n<li>If he didn't deny the allegations, that is the equivalent of pressing a self-destruct button.</li>\n<li>If he stayed silent or refused to answer, he would be seem cowardly and suspicious.</li>\n</ol>\n<p>Despite having a solid argument: &quot;If I did fake it, should Apple let it live for months?&quot;, that argument could still be seen as the third case above.</p>\n<h3 id=\"dark-pattern\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#dark-pattern\" aria-hidden=\"true\">#</a> &quot;Dark Pattern&quot;</h3>\n<p>When Flappy Bird became popular, many experts found it hard to explain what led to this success. An article named <a href=\"https://www.businessinsider.in/a-dark-pattern-in-flappy-bird-reveals-how-apples-mysterious-app-store-ranking-algorithm-works/articleshow/30292704.cms\">&quot;A 'Dark Pattern' In Flappy Bird Reveals How Apple's Mysterious App Store Ranking Algorithm Works&quot;</a> on Business Insider proposed a theory that Flappy Bird used &quot;Dark Pattern&quot; (a clever design to trick users into doing something):</p>\n<blockquote>\n<p>In earlier versions of the game, there was a &quot;rate&quot; button at the end of each play session, and this button was placed in the same location that the player would tap to play. As a result, when the user wanted to continue playing, it was easy to hit the rate button instead.</p>\n</blockquote>\n<p>Below is a photo taken from a <a href=\"https://youtu.be/fQoJZuBwrkU\">video on IGN's Youtube channel demonstrating an older version of Flappy Bird on IOS</a>:</p>\n<div class=\"flex w-full gap-4 md:gap-8\">\n  <figure class=\"flex-1\">\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/ios_title_screen.png\" alt=\"IOS Title screen\" />\n    <figcaption class=\"text-center\">Title screen</figcaption>\n  </figure>\n  <figure class=\"flex-1\">\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/ios_game_over.png\" alt=\"IOS Game over\" />\n    <figcaption class=\"text-center\">Game over</figcaption>\n  </figure>\n</div>\n<p>And below are the same screens in later updates:</p>\n<div class=\"flex w-full gap-4 md:gap-8\">\n  <figure class=\"flex-1\">\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/android_title_screen.png\" alt=\"Android Title screen\" />\n    <figcaption class=\"text-center\">Title screen</figcaption>\n  </figure>\n  <figure class=\"flex-1\">\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/android_game_over.png\" alt=\"Android Game over\" />\n    <figcaption class=\"text-center\">Game over</figcaption>\n  </figure>\n</div>\n<p>On both screens, the Play button was consistently on the left, and the Rate button isn't even on the Game Over screen. Tricks such as using colors to draw attention, or swapping placement of buttons are nowhere to be found.</p>\n<p>If you think it's suspiciously not user-friendly to put the Play button on the left side, and that this was done in hopes of getting people to click on the Share button, then here are some counter-arguments:</p>\n<ol>\n<li>Around 10% of the world's population are left-handed.</li>\n<li>Most languages are read from left to right, so placing the Play button on the left makes players see it first.</li>\n</ol>\n<h2 id=\"allegation-2-isn-t-a-good-game\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#allegation-2-isn-t-a-good-game\" aria-hidden=\"true\">#</a> Allegation 2: Isn't a good game</h2>\n<h3 id=\"empty-design\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#empty-design\" aria-hidden=\"true\">#</a> Empty design</h3>\n<p>When Flappy Bird became popular, many people deemed it to be too simple and hollow - there wasn't even any music, and sounds were minimal too. Therefore, it was undeserving of its popularity:</p>\n<p><em>Quoted from <a href=\"https://www.ibtimes.co.uk/six-ways-flappy-bird-pure-evil-1434949\">&quot;Six Ways Flappy Bird is Actually Pure Evil&quot;</a>:</em></p>\n<blockquote>\n<p>Once you've passed one gap in Flappy Bird, and scored one point, that's the game. There's nothing else to be gained from it.</p>\n<p>After that it is nothing but a repetition of that first successful act for as long as you can muster.</p>\n<p>There is no escalation, no alteration in the size or regularity of the gaps, and it offers no sense of fun either in its visuals or its sound design. Flappy Bird is a simple evil, like stubbing your toe, kneeling on a piece of Lego or a swift kick between the legs.</p>\n</blockquote>\n<p>The writer of this article used pretty strong language. Perhaps they were feeling extreme, or perhaps it's just an act to bring in more views.</p>\n<p>A critique of Flappy Bird often cited and praised was  <a href=\"https://web.archive.org/web/20140205023947/https://www.theatlantic.com/technology/archive/2014/02/the-squalid-grace-of-flappy-bird/283526\">&quot;The Squalid Grace of Flappy Bird&quot;</a> from The Atlantic. This article was passionate and detailed, though also a bit too lengthy. The author recognized Flappy Bird's design as simple - even simpler than Tetris or Go, but without the depth found in the latter two. They also deemed the game flow to be too static, lacking ups and downs.</p>\n<p>I can somewhat understand where the author was coming from, but I still disagree. For simple games like Flappy Bird, having depth is ideal, but a lack of fluctuation in flow is not always a downside. Because the design is as minimalistic as possible: no music, no special effects, and very little sound - the game easily puts the player into the state of flow (highly concentrated mentally, or &quot;the zone&quot;). The difficulty of the game works to its advantage: it forces players to focus harder on every action, which then leads to them entering &quot;the zone&quot;.</p>\n<p>Rather than comparing it to Tetris or Go, Flappy Bird should be compared to skipping rope or juggling in real life. These games are difficult at first, but once you get used to them, the difficulty starts to stem how long you can stay in the zone and not make mistakes. Judging from this point of view, Flappy Bird has an advantage over other, more complex endless runners like Jetpack Joyride.</p>\n<p>The legendary game developer Benett Foddy, creator of classic &quot;<a href=\"https://en.wikipedia.org/wiki/Getting_Over_It_with_Bennett_Foddy\">Getting Over It</a>&quot; even said:</p>\n<blockquote>\n<p><a href=\"https://www.theguardian.com/technology/2014/feb/10/flappy-bird-is-dead-but-brilliant-mechanics-made-it-fly\">What makes Flappy Bird work particularly well is that it eliminates all extraneous complexity to focus on one very simple input mechanic.</a></p>\n</blockquote>\n<h3 id=\"unrealistic-physics\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#unrealistic-physics\" aria-hidden=\"true\">#</a> Unrealistic physics</h3>\n<p>We all know Flappy Bird is a hard game, but many people think the game is hard because the game's physics are not realistic. This is both true and false, according to <a href=\"https://fnoschese.wordpress.com/2014/01/30/flappy-bird-when-reality-seems-unrealistic\">a scientific article on Action-Reaction that delves into the physics of the game</a>:</p>\n<blockquote>\n<p><strong>TL;DR:</strong> Is the physics in Flappy Bird realistic? Yes AND no.</p>\n<ul>\n<li><strong>YES:</strong> The gravitational pull is constant, producing a constant downward acceleration of 9.8 m/s/s (if we scale the bird to the size of a robin).</li>\n<li><strong>NO:</strong> The impulse provided by each tap is variable in order to produce the same post-tap velocity. In real life, the impulse from each tap would be constant and produce the same change in velocity.</li>\n</ul>\n</blockquote>\n<p>But being realistic or not doesn't really matter much, because fun is always more important than realism. Why does Mario, a human, jump 3-4 times as high as their own height? Why do we have floating dirt blocks in Minecraft? It's all because that made those games more fun, and the player experience smoother.</p>\n<h2 id=\"allegation-3-negative-impact-on-players\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#allegation-3-negative-impact-on-players\" aria-hidden=\"true\">#</a> Allegation 3: Negative impact on players</h2>\n<p>Around the start of 2014, Flappy Bird spread everywhere as &quot;the simple game that was somehow addictive&quot;. Of course, <a href=\"https://www.buzzfeednews.com/article/alanwhite/11-people-whove-had-their-lives-ruined-by-flappy-bird\">most people only exaggerated it as a joke on social media</a>. However, the press and media didn't get the joke, and presented this phenomenon in an absurd light, treating Flappy Bird as some kind of new addictive drug. Worse still, a few news publishers even accused the game of being intentionally designed to negatively impact players...</p>\n<p><em>Quoted from <a href=\"https://www.esquire.com/lifestyle/cars/a27142/flappy-bird-addictive\">&quot;Why Flappy Bird Was So Addictive&quot;</a> from Esquire:</em></p>\n<blockquote>\n<p>Flappy Bird has a relentlessly habit-forming quality that's hard to explain.</p>\n</blockquote>\n<blockquote>\n<p>There's got to be a psychological explanation for Flappy Bird's massive success.</p>\n</blockquote>\n<p>More than a few have tried to crack the code, <a href=\"https://www.google.com/search?q=flappy%20bird%20%22just%20one%20more%22\">usually pointing to the just-one-more effect</a> (it was even <a href=\"http://web.archive.org/web/20240202155249/https://newtz.shop/products/just-one-more-game-flappy-bird\">printed on shirts!</a>!). The just-one-more effect is when we tell ourselves &quot;just one more bite/episode&quot;, or in this case, &quot;just one more round&quot;. But when that round ends, you still want &quot;just one more round&quot;, and the cycle repeats itself... With Flappy Bird, this effect was more pronounced, since each round is only a few seconds, and the player can easily retry immediately. The player's flow doesn't even have to end before a new round starts. But claiming this to be intentionally designed to cause addiction is far-fetched.</p>\n<p>It is unfair to label a game as &quot;intentionally creating addicts&quot; just for its design of short rounds and simplicity. As mentioned above, Flappy Bird should be compared to skipping rope or juggling - the length of each round is short, and starting a new round is near instant. Would you say that those traditional games were also designed to be addictive?</p>\n<p>In <a href=\"https://www.forbes.com/sites/lananhnguyen/2014/02/11/exclusive-flappy-bird-creator-dong-nguyen-says-app-gone-forever-because-it-was-an-addictive-product\">an exclusive interview with Forbes</a>, Nguyen Ha Dong said:</p>\n<blockquote>\n<p>Flappy Bird was designed to play in a few minutes when you are relaxed.</p>\n</blockquote>\n<p>Mark Griffiths, Director of the International Gaming Research Unit and Professor of Gambling Studies at Nottingham Trent University wrote an article named <a href=\"https://theconversation.com/flappy-bird-obsession-is-not-necessarily-an-addiction-22638\">&quot;Flappy Bird obsession is not necessarily an addiction&quot;</a>, explaining that being attracted by Flappy Bird doesn't necessarily mean being so addicted it negatively impacts your life.</p>\n<h3 id=\"fabricated-events\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#fabricated-events\" aria-hidden=\"true\">#</a> Fabricated events</h3>\n<p>During the Flappy Bird craze at the start of 2014, more than a few news sites saw this as an opportunity to publish articles with shocking and dishonest titles about it to generate views. For example, many English news sites published about a teen stabbing his brother to death because he played Flappy Bird too well. After some digging, I've tracked the news back to the blog <a href=\"https://en.wikipedia.org/wiki/Huzlers\">Huzlers</a>, an obvious fake news site.</p>\n<figure class=\"w-full\">\n  <img class=\"w-full\" src=\"https://web.archive.org/web/20240208080617im_/https://media-cdn-v2.laodong.vn/storage/newsportal/Uploaded/luuthienhuong/2014_02_08/game_GZAC.JPG?w=660\" alt=\"Huzlers\" />\n  <figcaption class=\"text-center\">Huzlers's article</figcaption>\n</figure>\n<p>This article was debunked by more trustworthy sources. A video by TheGamerFromMars: <a href=\"https://youtu.be/ojtlZZJYigo\">&quot;The Flappy Bird Murder - Internet Mysteries&quot;</a> debunked the article in great detail from an overview perspective.</p>\n<h3 id=\"dong-s-reaction\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#dong-s-reaction\" aria-hidden=\"true\">#</a> Dong's reaction</h3>\n<p>Despite almost all stories of &quot;Flappy Bird ruining someone's life&quot; being fake or overexaggerated, Nguyen Ha Dong seems to have believed some of them. In the same <a href=\"https://www.forbes.com/sites/lananhnguyen/2014/02/11/exclusive-flappy-bird-creator-dong-nguyen-says-app-gone-forever-because-it-was-an-addictive-product\">interview with Forbes</a> as above, Dong said:</p>\n<blockquote>\n<p>Flappy Bird was designed to play in a few minutes when you are relaxed, but it happened to become an addictive product. I think it has become a problem. To solve that problem, it's best to take down Flappy Bird.</p>\n</blockquote>\n<p><em>Quoted from <a href=\"https://www.rollingstone.com/culture/culture-news/the-flight-of-the-birdman-flappy-bird-creator-dong-nguyen-speaks-out-112457\">his interview with RollingStone</a>, from the perspective of the reporter</em></p>\n<blockquote>\n<p>He hands me his iPhone so that I can scroll through some messages he’s saved. One is from a woman chastising him for &quot;distracting the children of the world.&quot; Another laments that &quot;13 kids at my school broke their phones because of your game, and they still play it cause it’s addicting like crack.&quot; Nguyen tells me of e-mails from workers who had lost their jobs, a mother who had stopped talking to her kids. &quot;At first I thought they were just joking,&quot; he says, &quot;but I realize they really hurt themselves.&quot; Nguyen - who says he botched tests in high school because he was playing too much Counter-Strike - genuinely took them to heart.</p>\n</blockquote>\n<p>On Twitter, Nguyen Ha Dong had shown to be a bit gullible to overexaggeration jokes from the internet, advising players to take breaks and play Flappy Bird in a more healthy manner:</p>\n<blockquote>\n<p><a href=\"https://twitter.com/currllzzz/status/428825193646006273\"><strong>Twitter User</strong>: lol im never gonna get some sleep now with these games 😭</a></p>\n<p><a href=\"https://twitter.com/dongatory/status/428825578465021953\"><strong>Dong:</strong> Have a good night :-) Give my games a break too.</a></p>\n</blockquote>\n<blockquote>\n<p><strong>Twitter User</strong>: i have been flappy bird for 3 hours straight its the most addicting thing ever</p>\n<p><a href=\"https://twitter.com/dongatory/status/428404148166348800\"><strong>Dong:</strong> That is too much. Please give yourself and the game a break :D</a></p>\n</blockquote>\n<blockquote>\n<p><strong>Twitter User</strong>: FLAPPY BIRD HAS RUINED MY LIFE! I'VE BEEN PLAYING IT FOR 8 HOURS STRAIGHT AND I SWEAR MY AYS ARE BLEEDING</p>\n<p><a href=\"https://twitter.com/dongatory/status/427191004744003584\"><strong>Dong:</strong> It's just a game. Take care of yourself first. I don't make game to ruin people lives.</a></p>\n</blockquote>\n<p>He often had to receive such messages, and they all added pressure to his psyche. Eventually, he couldn't take anymore. As we all know, Mr. Dong had removed Flappy Bird from all app stores, hoping to end the &quot;addiction&quot; of his game.</p>\n<h2 id=\"allegation-4-violating-mario-s-copyright\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#allegation-4-violating-mario-s-copyright\" aria-hidden=\"true\">#</a> Allegation 4: Violating Mario's copyright</h2>\n<p>We have arrived at the important part. This allegation what motivated me to write this blog post. Most news sites cite Kotaku's article <a href=\"https://kotaku.com/flappy-bird-is-making-50-000-a-day-off-ripped-art-1517498140\">&quot;Flappy Bird Is Making $50,000 A Day Off Ripped Art&quot;</a> when making the copyright argument. Reading through the article, we can easily see how sensational the author is being:</p>\n<p>Firstly, the author mentioned how Nguyen Ha Dong made a lot of money from the game:</p>\n<blockquote>\n<p>Flappy Bird has gotten so big that its creator, Dong Nguyen, told The Verge he's making $50,000 a day on ad revenue. $50,000 a day! That's $18 million a year, FYI.</p>\n</blockquote>\n<p>This is a manipulation tactic to create distance between the reader and the target that the article wants to criticize. By first mentioning how much income he was making, the readers would feel like Mr. Dong is nothing like them, and therefore would empathize with him less. Then the author added:</p>\n<blockquote>\n<p>Most people acknowledge that it's a terrible game - which it is.</p>\n</blockquote>\n<p>As elaborated in the Allegation 2 above, this is debatable. And at the end of the article, the author concluded:</p>\n<blockquote>\n<p>Let this be a life lesson: if you want to make $50,000 a day, put ripped art in a terrible game.</p>\n</blockquote>\n<p>By doing so, the author seems to want to hammer in the fact that Dong is an unethical game designer who did not deserve his success. Overall, this article wants to cause anger. <a href=\"https://www.technologyreview.com/2013/09/16/176450/most-influential-emotions-on-social-networks-revealed\">A research from MIT</a> showed that posts that caused anger were 3 times as likely to be shared on social media compared to other emotions. I think it's safe to assume that the author was intentionally trying to achieve the same effect by presenting heavily biased claims.</p>\n<p>Now let's take a closer look at the arguments stated in the article. Most of them revolve around Mr. Dong stealing art and sound assets from Nintendo's Mario series.</p>\n<h3 id=\"stealing-sound-effects\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#stealing-sound-effects\" aria-hidden=\"true\">#</a> Stealing sound effects</h3>\n<p><em>Quoted from <a href=\"https://kotaku.com/flappy-bird-is-making-50-000-a-day-off-ripped-art-1517498140\">the article from Kotaku</a>:</em></p>\n<blockquote>\n<p>The twinkly sound effect when your bird flies between pipes is heavily inspired by Mario's coin-collecting chime, to the point where they sound nearly identical.</p>\n</blockquote>\n<p>This is the collecting coin sound effects throughout the history of Mario games:</p>\n<iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/gdPFOF91xb0\" title=\"Super Mario Coin Sound Effect Evolution (1983-2020)\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n<p>And this is Flappy Bird's:</p>\n<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" allow=\"autoplay\" src=\"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/80713508&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true\"></iframe>\n<p>They are both chimes, but they are definitely not identical. Many platformer games like DuckTales or Shovel Knight use similar sound effects. For example, this sound plays when collecting rings in Sonic:</p>\n<iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/n9GImjHkLmE\" title=\"Sonic Ring - Sound Effect (HD)\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n<p>Sounds in Flappy Birds were not only not taken from Mario, but also had a different style. This becomes even clearer when we hear Dong's comment. A month before releasing Flappy Bird, Dong posted on Twitter:</p>\n<blockquote>\n<p><a href=\"https://twitter.com/dongatory/status/322298468955734016\"><strong>Dong:</strong> Having a lot of fun working to add SFX into games. There are surprisingly a lot of royalty-free SFX on various of websites.</a></p>\n<p><a href=\"https://twitter.com/dongatory/status/322299140518338561\"><strong>Dong:</strong> So my remaining tasks are pretty simple: Edit the sound a little bit using GarageBand and add them into the game.</a></p>\n</blockquote>\n<p>This is common practice for indie game developers who don't have enough resource to hire sound effect artists, and also what's recommended for most beginners. Mr. Dong also has a <a href=\"https://soundcloud.com/dong-nguyen-ha\">Soundcloud account where he posts sound effects that he makes and uses</a>, you should check it out!</p>\n<h3 id=\"stealing-background\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#stealing-background\" aria-hidden=\"true\">#</a> Stealing background</h3>\n<p><em>Quoted from <a href=\"https://kotaku.com/flappy-bird-is-making-50-000-a-day-off-ripped-art-1517498140\">the article from Kotaku</a>:</em></p>\n<blockquote>\n<p>The backgrounds also appear to be heavily inspired by Mario.</p>\n</blockquote>\n<a href=\"https://www.spriters-resource.com/mobile/flappybird/sheet/59894\">\n  <figure>\n    <div class=\"flex w-full gap-4 md:gap-8\">\n      <img class=\"m-0 flex-1\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/flappy_bird_background_day.png\" alt=\"Flappy Bird Background Day\" />\n      <img class=\"m-0 flex-1\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/flappy_bird_background_night.png\" alt=\"Flappy Bird Background Night\" />\n    </div>\n    <figcaption class=\"text-center\">Flappy Bird's Backgrounds</figcaption>\n  </figure>\n</a>\n<p>I also managed to find every background of <a href=\"https://www.mariowiki.com/Big-City\">Big City</a> in &quot;Donkey Kong&quot; (Game Boy) and <a href=\"https://www.mariowiki.com/Mario_Toy_Company\">Mario Toy Company</a> in &quot;Mario vs. Donkey Kong&quot;, both also rare appearances of modern cities in Mario:</p>\n<a href=\"https://www.spriters-resource.com/game_boy_gbc/dk/sheet/30087\">\n  <figure>\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/big_city.png\" alt=\"Big City Background\" />\n    <figcaption class=\"text-center\">Big City</figcaption>\n  </figure>\n</a>\n<a href=\"https://www.spriters-resource.com/game_boy_advance/mariovsdk/sheet/146\">\n  <figure>\n    <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/mario_toy_company.png\" alt=\"Mario Toy Company Background\" />\n    <figcaption class=\"text-center\">Mario Toy Company</figcaption>\n  </figure>\n</a>\n<p>And they don't look similar to Flappy Bird's background at all. The only commonality is that they're both pixel art modern cities. That hardly counts as &quot;heavily inspired&quot;, because if so, then games like  <a href=\"https://en.wikipedia.org/wiki/Mega_Man\">Mega Man</a>, <a href=\"https://en.wikipedia.org/wiki/Kero_Blaster\">Kero Blaster</a>, <a href=\"https://en.wikipedia.org/wiki/River_City_Ransom\">River City Ransom</a>, etc. would all be &quot;heavily inspired by Mario&quot;?</p>\n<h3 id=\"green-pipes-and-faby\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#green-pipes-and-faby\" aria-hidden=\"true\">#</a> Green pipes and Faby</h3>\n<p><em>Quoted from <a href=\"https://kotaku.com/flappy-bird-is-making-50-000-a-day-off-ripped-art-1517498140\">the article from Kotaku</a>:</em></p>\n<blockquote>\n<p>Look at the pipes, for example:</p>\n<p><img src=\"https://web.archive.org/web/20140207080213im_/http://img.gawkerassets.com/img/19evahld5d6ydpng/ku-xlarge.png\" alt=\"Kotaku pipe Eg\" /></p>\n<p>On the left is Flappy Bird; on the right is Super Mario World.</p>\n</blockquote>\n<p>To reiterate, the only commonality between these images are that they are both green pipes. Flappy Bird did not steal from Mario. I even gathered images of pipes in almost all 2D pixel art Mario games for comparison:</p>\n<div class=\"flex flex-col gap-4\" x-data=\"{\n    flappy_bird_pipes: {\n      'Flappy Bird v1.0': '59537.png',\n      'Flappy Bird v1.2': '59894.png',\n    },\n    mario_pipes: {\n      'Mario Bros.': 'MB_Arcade_Warp_Pipe_Sprite.png',\n      'Mario Bros. (Atari 2600)': 'MB_Atari_2600_Warp_Pipe_Sprite.png',\n      'Mario Bros. (Atari 5200)': 'MB5200Pipe.png',\n      'Mario Bros. (Atari 7800)': 'MB7800Pipe.png',\n      'Mario Bros. (NES)': 'MarioBrosNESWarpPipe.png',\n      'Super Mario Bros.': 'Warp_Pipe_SMB.png',\n      'Super Mario Bros. Special': 'SMBS_Sharp_X1_Warp_Pipe.png',\n      'Super Mario Bros. 3': 'WarpPipeSMB3.png',\n      'Super Mario Bros. 3 (Mario Bros.)': 'MBSMB3_Warp_Pipe.png',\n      'Super Mario Land': 'SML_Warp_Pipe_Sprite.png',\n      'Super Mario World': 'Warp_Pipe_SMW.png',\n      'Super Mario Land 2: 6 Golden Coins': 'CHB123SML2Pipe2.png',\n      'Super Mario All-Stars': 'SMASSMB_Pipe.png',\n      'Super Mario All-Stars (Super Mario Bros. 3)': 'SMAS_SMB3_Warp_Pipe_sprite.png',\n      'Super Mario World 2: Yoshi\\'s Island': 'SMW2_Warp_Pipe.png',\n    },\n    flappy_bird_pipe: 'Flappy Bird v1.0',\n    mario_pipe: 'Super Mario World',\n  }\">\n  <div class=\"flex w-full flex-col items-center justify-center gap-y-4 gap-x-8 overflow-hidden rounded-xl bg-base-300 p-4 sm:flex-row\">\n    <div class=\"diff aspect-square md:flex-1\">\n      <div class=\"diff-item-1\">\n        <img class=\"-translate-y-8 scale-90 bg-base-300\" :src=\"`https://codeberg.org/NNB/blog-images/raw/branch/main/16/pipe/${mario_pipes[mario_pipe]}`\" alt=\"Mario's Pipe\" style=\"\n            image-rendering: pixelated;\n            image-rendering: -moz-crisp-edges;\n            image-rendering: crisp-edges;\n          \" />\n      </div>\n      <div class=\"diff-item-2\">\n        <img class=\"-translate-y-8 scale-90 bg-base-300\" :src=\"`https://codeberg.org/NNB/blog-images/raw/branch/main/16/pipe/${flappy_bird_pipes[flappy_bird_pipe]}`\" alt=\"Flappy Bird's Pipe\" style=\"\n            image-rendering: pixelated;\n            image-rendering: -moz-crisp-edges;\n            image-rendering: crisp-edges;\n          \" />\n      </div>\n      <div class=\"diff-resizer\"></div>\n    </div>\n    <div class=\"diff aspect-square md:flex-1\">\n      <div class=\"diff-item-1\">\n        <img class=\"-translate-y-8 rotate-90 scale-90 bg-base-300\" :src=\"`https://codeberg.org/NNB/blog-images/raw/branch/main/16/pipe/${mario_pipes[mario_pipe]}`\" alt=\"Mario's Pipe\" style=\"\n            image-rendering: pixelated;\n            image-rendering: -moz-crisp-edges;\n            image-rendering: crisp-edges;\n          \" />\n      </div>\n      <div class=\"diff-item-2\">\n        <img class=\"-translate-y-8 rotate-90 scale-90 bg-base-300\" :src=\"`https://codeberg.org/NNB/blog-images/raw/branch/main/16/pipe/${flappy_bird_pipes[flappy_bird_pipe]}`\" alt=\"Flappy Bird's Pipe\" style=\"\n            image-rendering: pixelated;\n            image-rendering: -moz-crisp-edges;\n            image-rendering: crisp-edges;\n          \" />\n      </div>\n      <div class=\"diff-resizer\"></div>\n    </div>\n  </div>\n  <div class=\"flex flex-col gap-4 sm:flex-row\">\n    <select class=\"select-bordered select flex-1\" x-model=\"flappy_bird_pipe\">\n      <template x-for=\"(image, game) in flappy_bird_pipes\" :key=\"game\">\n        <option x-text=\"game\"></option>\n      </template>\n    </select>\n    <select class=\"select-bordered select flex-1\" x-model=\"mario_pipe\">\n      <template x-for=\"(image, game) in mario_pipes\" :key=\"game\">\n        <option x-text=\"game\"></option>\n      </template>\n    </select>\n  </div>\n</div>\n<p><em>(You can choose other Mario games to compare.)</em></p>\n<p>Flappy Bird's pipe matched none of them. Next, we have the bird, Faby:</p>\n<p><em>Quoted from <a href=\"https://kotaku.com/flappy-bird-is-making-50-000-a-day-off-ripped-art-1517498140\">the article from Kotaku</a>:</em></p>\n<blockquote>\n<p>What about the bird itself? While the eponymous Flappy Bird isn't a direct ripoff, it appears to be a cross between the Spike and Cheep Cheep enemies in Super Mario Bros. 3. See if you can spot the similarities:</p>\n<p><img src=\"https://web.archive.org/web/20140207080214im_/http://img.gawkerassets.com/img/19evahlcyexmmpng/ku-xlarge.png\" alt=\"Kotaku bird Eg\" /></p>\n<p>(Left: Flappy Bird. Right/Top: Spike. Right/Bottom: Cheep-Cheep.)</p>\n</blockquote>\n<p>Here, the author did admit that it wasn't &quot;direct theft&quot; so I won't be compiling similar assets from Mario.</p>\n<h3 id=\"fair-use\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#fair-use\" aria-hidden=\"true\">#</a> Fair use</h3>\n<p>Flappy Bird haters (if they still exist) might be thinking: &quot;Not stealing directly doesn't mean free of plagiarism, Dong admitted himself that he was inspired by Mario!&quot;</p>\n<p>It is true that he took some inspiration from Mario.</p>\n<blockquote>\n<p>The year before, he’d drawn a pixelated bird on his computer that riffed on Nintendo fish, called <a href=\"https://www.mariowiki.com/Cheep_Cheep\">Cheep Cheeps</a>. He drew green pipes - a homage to Super Mario Bros. - that the bird would have to navigate.</p>\n</blockquote>\n<p>When the internet suspect him of copyright violation against Nintendo, he answered:</p>\n<blockquote>\n<p><a href=\"https://twitter.com/dongatory/status/430415793352749056\"><strong>Dong:</strong> I think I stole their games' spirit but I didn't rip-off their work.</a></p>\n</blockquote>\n<p>He's right. Those who claim copyright infringement between Mario and Flappy Bird are ignoring <a href=\"https://en.wikipedia.org/wiki/Fair_use\">Fair Use</a>. Fair use allows the use of a copyrighted work or components of a copyrighted product for educational purposes or for evaluation purposes. Fair use also considers the quantity and quality of the work used to determine whether a product infringes the copyright of other products.</p>\n<p>This law exists to limit individuals and organizations that may use their monopoly to limit the development of science and art, and at the same time, allow others to be inspired, transform, and improve products that already exist. Let's compare Flappy Bird with Mario:</p>\n<p>Firsly, Faby. I won't be comparing it to <a href=\"https://www.mariowiki.com/Spike\">Spike</a> because honestly, the only thing they have in common are think beaks. Comparing it to <a href=\"https://www.mariowiki.com/Cheep_Cheep\">Cheep-Cheep</a>, here are some commonalities:</p>\n<ul>\n<li>Round shape.</li>\n<li>Big mouth.</li>\n<li>White wings.</li>\n<li>Large eyes.</li>\n</ul>\n<p>And for the differences:</p>\n<table>\n<thead>\n<tr>\n<th>Faby</th>\n<th>Cheep-Cheep</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Is a bird</td>\n<td>Is a fish</td>\n</tr>\n<tr>\n<td>Yellow body</td>\n<td>Red body with white belly</td>\n</tr>\n<tr>\n<td>Have no tail nor fins</td>\n<td>Have tail and fins</td>\n</tr>\n</tbody>\n</table>\n<p>They are not only two entirely different species, but even the parts that they have in common have slight differences:</p>\n<table>\n<thead>\n<tr>\n<th>Faby</th>\n<th>Cheep-Cheep</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Thin, long beak</td>\n<td>Thick, round lips</td>\n</tr>\n<tr>\n<td>Small wings at low position</td>\n<td>Large fins at high position</td>\n</tr>\n<tr>\n<td>The eye is 1/4th its size</td>\n<td>Smaller eyes</td>\n</tr>\n</tbody>\n</table>\n<p>It's not enough to compare only looks. They are also used for completely different purposes, and interact with the world differently:</p>\n<table>\n<thead>\n<tr>\n<th>Faby</th>\n<th>Cheep-Cheep</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Player-controlled character</td>\n<td>Hostile enemy</td>\n</tr>\n<tr>\n<td>Flies infinitely in arcs</td>\n<td>Swim straight underwater or hop in and out of water</td>\n</tr>\n</tbody>\n</table>\n<p>What about the green pipes? Well, you know, those actually exists in real life:</p>\n<div class=\"grid gap-4 sm:grid-cols-2\">\n  <div class=\"aspect-video overflow-hidden sm:aspect-[4/3]\"><img class=\"m-0 h-full w-full object-cover object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/green_pipe_irl0.jpg\" alt=\"Green pipe IRL 1\" /></div>\n  <div class=\"aspect-video overflow-hidden sm:aspect-[4/3]\"><img class=\"m-0 h-full w-full object-cover object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/green_pipe_irl1.jpg\" alt=\"Green pipe IRL 2\" /></div>\n  <div class=\"aspect-video overflow-hidden sm:aspect-[4/3]\"><img class=\"m-0 h-full w-full object-cover object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/green_pipe_irl2.jpg\" alt=\"Green pipe IRL 3\" /></div>\n  <div class=\"aspect-video overflow-hidden sm:aspect-[4/3]\"><img class=\"m-0 h-full w-full object-cover object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/green_pipe_irl3.jpg\" alt=\"Green pipe IRL 4\" /></div>\n</div>\n<p>Pipes that are big, bright green, and has thick edges like Mario exist in real life, not just a brainchild of Nintendo. But if you think about it, the concept of &quot;green water pipes&quot; is very general and has existed or been applied in many fields. It itself cannot be copyrighted by any individual or organization. But just to be sure, let's compare the pipes in Flappy Bird with Mario:</p>\n<table>\n<thead>\n<tr>\n<th>In Flappy Bird</th>\n<th>In Mario</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Player character dies on contact</td>\n<td>Blocks the player's movement</td>\n</tr>\n<tr>\n<td>Can't be interacted with</td>\n<td>Can sometimes go into and out of or warp between worlds</td>\n</tr>\n</tbody>\n</table>\n<p>Once again, the way pipes are used is very different between the two games. So why did Mr. Dong use pipes like Mario and not something else like a brick wall or laser?</p>\n<p>No art exists in a vacuum, neither does Flappy Bird. Flappy Bird is a video game, video game is art, and art is a conversation. A conversation between artists, from generation to generation, to learn, cultivate, grow. Nguyen Ha Dong used the image of a green pipe like in Mario not to piggyback of Mario's popularity or because he was lazy to create another image. He uses it precisely because it is a symbol of video games in general in the childhood of his generation. He seems to want to give players a ticket back to childhood, taking them back to simpler times. Simple like the design of Flappy Bird it's self. Remember, simplicity is what he really aims for.</p>\n<h3 id=\"nintendo-and-inspired-games\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#nintendo-and-inspired-games\" aria-hidden=\"true\">#</a> Nintendo and inspired games</h3>\n<p>There are many games on the market that are much more strongly inspired by Nintendo games than Flappy Bird, yet have not received much criticism, or are even praised for bringing back nostalgic memories. Classic examples include <a href=\"https://en.wikipedia.org/wiki/Braid_(video_game)\">Braid</a>, inspired by Mario <a href=\"https://www.mariowiki.com/Super_Mario_Bros.\">Super Mario Bros</a>:</p>\n<p>An enemy in Braid, <a href=\"https://braid.fandom.com/wiki/Monstar\">Monstar</a>, has almost identical sprite and behaviors to the <a href=\"https://www.mariowiki.com/Goomba\">Goomba</a> from Mario:</p>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/braid_monstar.webp\" alt=\"Monstar\" />\n    </div>\n    <figcaption class=\"text-center\">Monstar (Braid)</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/mario_goomba.svg\" alt=\"Goomba\" />\n    </div>\n    <figcaption class=\"text-center\">Goomba (Mario)</figcaption>\n  </figure>\n</div>\n<p>The same is true with <a href=\"https://braid.fandom.com/wiki/Claw\">Claw</a> (Braid) and <a href=\"https://www.mariowiki.com/Piranha_Plant\">Piranha Plant</a> (Super Mario Bros):</p>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/braid_claw.webp\" alt=\"Claw\" />\n    </div>\n    <figcaption class=\"text-center\">Claw (Braid)</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center sm:h-64\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/mario_piranha_plant.png\" alt=\"Piranha Plant\" style=\"\n          image-rendering: pixelated;\n          image-rendering: -moz-crisp-edges;\n          image-rendering: crisp-edges;\n        \" />\n    </div>\n    <figcaption class=\"text-center\">Piranha Plant (Mario)</figcaption>\n  </figure>\n</div>\n<p>Level <a href=\"https://braid.fandom.com/wiki/4-2:_Jumpman\">4-2</a> in Braid is heavily inspired by the game <a href=\"https://www.mariowiki.com/Donkey_Kong_(game)\">Donkey Kong</a>, and the level's name is also &quot;Jumpman&quot; (nickname for Mario before Mario was renamed):</p>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-48 object-cover object-[40%_center] sm:max-h-96\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/braid_4_2.png\" alt=\"Braid 4-2\" />\n    </div>\n    <figcaption class=\"text-center\">4-2: Jumpman (Braid)</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-48 object-contain object-center sm:max-h-96\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/mario_donkey_kong.png\" alt=\"Donkey Kong\" style=\"\n          image-rendering: pixelated;\n          image-rendering: -moz-crisp-edges;\n          image-rendering: crisp-edges;\n        \" />\n    </div>\n    <figcaption class=\"text-center\">25m (Donkey Kong)</figcaption>\n  </figure>\n</div>\n<p>At the end of each world in Braid, a character will appear to tell the player that &quot;the princess is in another castle&quot;, a reference to Mario:</p>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-48 object-cover object-center sm:max-h-96\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/braid_1_4.png\" alt=\"Braid 2-4\" />\n    </div>\n    <figcaption class=\"text-center\">End of level 2-4 (Braid)</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-48 object-contain object-center sm:max-h-96\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/mario_1_4.png\" alt=\"Super Mario Bros 1-4\" style=\"\n          image-rendering: pixelated;\n          image-rendering: -moz-crisp-edges;\n          image-rendering: crisp-edges;\n        \" />\n    </div>\n    <figcaption class=\"text-center\">End of level 1-4 (Super Mario Bros)</figcaption>\n  </figure>\n</div>\n<p>Both games are even from the same genre (<a href=\"https://en.wikipedia.org/wiki/Platformer\">Platformer</a>). But Braid is absolutely not a copycat. This game focuses more on puzzle elements with time manipulation mechanics. It uses many images from Mario because it wants players to quickly understand the basic mechanics of the game, then focus on the puzzle element. Not only that, it also creates a feeling of nostalgia, fooling players into thinking that the game is just a simple, fun game, then twisting that expectation. I want to avoid spoilers so I won't go into more detail.</p>\n<p>Mario wasn't the only product that became inspiration. 2nd example: <a href=\"https://en.wikipedia.org/wiki/Tunic_(video_game)\">TUNIC</a> inspired by <a href=\"https://zeldawiki.wiki/wiki/The_Legend_of_Zelda\">The Legend of Zelda</a>, both are <a href=\"https://en.wikipedia.org/wiki/Action-adventure_game\">action-adventure games</a> that focus on the player's exploration of an open world:</p>\n<div class=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n  <figure class=\"max-sm:col-span-2\">\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 aspect-square object-contain object-center\" src=\"https://upload.wikimedia.org/wikipedia/en/8/85/Tunic_cover_art.jpg\" alt=\"Tunic\" />\n    </div>\n    <figcaption class=\"text-center\">Tunic</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 aspect-square object-contain object-center\" src=\"https://cdn.wikimg.net/en/zeldawiki/images/2/27/TLoZ_FDS_Box.png\" alt=\"The Legend of Zelda\" />\n    </div>\n    <figcaption class=\"text-center\">The Legend of Zelda</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 aspect-square object-contain object-center\" src=\"https://cdn.wikimg.net/en/zeldawiki/images/c/c7/ALttP_JP_Box.jpg\" alt=\"The Legend of Zelda: A Link to the Past\" />\n    </div>\n    <figcaption class=\"text-center\">A Link to the Past</figcaption>\n  </figure>\n</div>\n<p>Tunic is heavily inspired by Zelda, but once again it's not just a clone. There are three videos on Youtube that elaborates this point quite well:</p>\n<ul>\n<li><a href=\"https://youtu.be/CuXWSS-X1YY\">&quot;Tunic is more than just a Zelda clone&quot;</a> by KevynTheJar</li>\n<li><a href=\"https://youtu.be/rYoZr24Zoao\">&quot;The Legacy of Zelda | How Tunic Embraces a Classic&quot;</a> by Transparency</li>\n<li><a href=\"https://youtu.be/aGssYfAS7Hs\">&quot;The Legend of Zelda (and how Tunic honors it)&quot;</a> by Liam Triforce</li>\n</ul>\n<p>There are lots of other examples: <a href=\"https://wikimon.net/Main_Page\">Digimon</a> inspired by <a href=\"https://bulbapedia.bulbagarden.net/wiki/Main_Page\">Pokémon</a>, <a href=\"https://en.wikipedia.org/wiki/Axiom_Verge\">Axiom Verge</a> from <a href=\"https://en.wikipedia.org/wiki/Metroid\">Metroid</a>, <a href=\"https://en.wikipedia.org/wiki/Antonblast\">Antonblast</a> from <a href=\"https://www.mariowiki.com/Wario\">Wario</a>...</p>\n<p>(Also, all of the games mentioned above are sold on <a href=\"https://en.wikipedia.org/wiki/Nintendo_eShop\">eShop</a>, Nintendo's own game platform for their console line)</p>\n<p>Below are some videos listing the times when non-Nintendo games were inspired by, reference, easter eggs or parodied Mario, whether officially collaborating with Nintendo or not:</p>\n<div class=\"grid gap-4 sm:grid-cols-2\">\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/A6ojk9jSZGI\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/hFanHyoK204\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/47No4sWlJsQ\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/9kAiPZXUXqE\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n</div>\n<p>Other games from Nintendo also get reference:</p>\n<div class=\"grid gap-4 sm:grid-cols-2 md:grid-cols-3\">\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/0wzRiE3Vkzo\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/cyRTTXAmcSI\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n  <iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/OKVJCbRvN9E\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n</div>\n<h3 id=\"nintendo-itself-gets-inspiration\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#nintendo-itself-gets-inspiration\" aria-hidden=\"true\">#</a> Nintendo itself gets inspiration</h3>\n<p>Steve Jobs once mentioned an interesting quote:</p>\n<blockquote>\n<p>Good artists copy. Great artists steal.</p>\n</blockquote>\n<p>Nintendo have a lot of great talent, so of course they also &quot;stolen&quot; from elsewhere, such as the game Donkey Kong (the first game in which Mario appeared):</p>\n<blockquote>\n<p>Donkey Kong was heavily inspired by 1930s American media. It was originally conceived as a <a href=\"https://en.wikipedia.org/wiki/Popeye\">Popeye</a> game, based on the 1930s comic and animation, with Bluto being in the role of Donkey Kong, Popeye being Mario, and Olive Oyl being Lady.</p>\n</blockquote>\n<p>Nintendo at that time owned the license to make games with characters from Popeye but for some technical reason, they had to change.</p>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center\" src=\"https://mario.wiki.gallery/images/6/63/MarioInDKArtwork.jpg\" alt=\"Jumpman\" />\n    </div>\n    <figcaption class=\"text-center\">Mario in Donkey Kong's poster</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center\">\n      <img class=\"m-0 h-full max-h-64 object-contain object-center\" src=\"https://upload.wikimedia.org/wikipedia/en/0/00/Popeye_the_Sailor.png\" alt=\"Popeye\" />\n    </div>\n    <figcaption class=\"text-center\">Popeye</figcaption>\n  </figure>\n</div>\n<blockquote>\n<p>The 1930s film <a href=\"https://en.wikipedia.org/wiki/King_Kong\">King Kong</a> would serve as another inspiration and the setting of the game was New York City.</p>\n</blockquote>\n<p>Like the movie King Kong, the villain in Nintendo's game is also a giant gorilla.</p>\n<p>And in the game Super Mario Bros: In <a href=\"https://geekculture.co/interview-with-toru-iwatani-creator-of-pac-man\">an interview with Geek Culture</a>, <a href=\"https://en.wikipedia.org/wiki/Toru_Iwatani\">Toru Iwatani</a> (father of Pac-Man) recounts:</p>\n<blockquote>\n<p>I worked on the sequel &quot;Pac-Land&quot; and &quot;Pac-Mania&quot; and my favorite is &quot;Pac-Land,&quot; which is the pioneer of action games with horizontally running background. Mr. <a href=\"https://en.wikipedia.org/wiki/Shigeru_Miyamoto\">Shigeru Miyamoto</a>, who developed &quot;Super Mario Bros.&quot; told me that the game was influenced by Namco’s <a href=\"https://en.wikipedia.org/wiki/Pac-Land\">&quot;PAC-LAND&quot;</a>.</p>\n</blockquote>\n<div class=\"grid grid-cols-2 gap-4\">\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-96 object-contain object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/super_mario_bros.jpg\" alt=\"Super Mario Bros\" />\n    </div>\n    <figcaption class=\"text-center\">Super Mario Bros</figcaption>\n  </figure>\n  <figure>\n    <div class=\"flex h-full items-center justify-center bg-black\">\n      <img class=\"m-0 h-full max-h-96 object-contain object-center\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/pac_land.jpg\" alt=\"Pac-Land\" />\n    </div>\n    <figcaption class=\"text-center\">Pac-Land</figcaption>\n  </figure>\n</div>\n<h3 id=\"official-response-from-nintendo\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#official-response-from-nintendo\" aria-hidden=\"true\">#</a> Official response from Nintendo</h3>\n<p>After announcing the &quot;death&quot; of Flappy Bird on social networks, Nguyen Ha Dong wrote a disclaimer:</p>\n<blockquote>\n<p><a href=\"https://twitter.com/dongatory/status/432228383095668737\"><strong>Dong:</strong> It is not anything related to legal issues. I just cannot keep it anymore.</a></p>\n</blockquote>\n<p>Because of aftereffects from Kotaku's allegations, many people were skeptical of Dong's statement. But that is true. In an email to The Wall Street Journal, Nintendo spokesman Yasuhiro Minagawa reiterated the company's previous statements, saying that Nintendo has not complained about Flappy Bird's similarities to the game Super Mario Bros:</p>\n<p><em>Quoted from Nintendo's spokesperson on <a href=\"https://www.wsj.com/articles/BL-DGB-32728\">an article from The Wall Street Journal</a>:</em></p>\n<blockquote>\n<p>While we usually do not comment on the rumors and speculations, we have already denied the speculation.</p>\n</blockquote>\n<p>If you thought Nintendo just said that because it wanted to avoid petty drama and maintain its image, you're wrong! Nintendo has a scandalous history of abusing copyright laws to satisfy an antiquated view of intellectual property:</p>\n<ul>\n<li>Nintendo has sent requests to remove many fan game products that Nintendo fans are passionate about. There are many large projects of equal quality to the games that Nintendo itself makes, for example <a href=\"https://metroid2remake.blogspot.com/\">&quot;AM2R&quot;</a>, <a href=\"https://www.pokemonuranium.org/\">&quot;Pokémon Uranium&quot;</a>, <a href=\"http://www.oot-2d.com/\">&quot;Ocarina Of Time 2D&quot;</a>, ... You can watch it through the video <a href=\"https://youtu.be/B9F8gRaRbas\">&quot;Fan Projects Taken Down by Nintendo&quot;</a> by T3rr0r for more details.</li>\n<li>While other game companies want Youtubers to make video about their games, even have to pay for it, Nintendo blocks monetization of all video with Nintendo's game. It wasn't until 2015 that the &quot;Nintendo Creators Program&quot; was open, allowing Youtubers to only receive 60% to 70% of video revenue. Not only that, Youtubers must register themselves to participate in the program and be accepted by Nintendo. It wasn't until the end of 2018 that Nintendo removed this program and allowed all YouTubers who played their games to make money freely.</li>\n<li>Many game companies spend their own money to organize e-sports tournaments, some even fail to attract fans (like Overwatch's esport tournament). Not only does Nintendo rarely organize tournaments, but they had also shutdown many tournaments that their dedicated fans organized.</li>\n</ul>\n<p>Not to mention there are many other cases, EmpLemon's Video <a href=\"https://youtu.be/xgKY9hmbfgo\">&quot;Sacrifices to the Church of Nintendo&quot;</a> summarizes many cases where Nintendo abused copyright law. And they didn't even sue the billion-dollar app Flappy Bird. This says it all!</p>\n<h3 id=\"as-for-kotaku\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#as-for-kotaku\" aria-hidden=\"true\">#</a> As for Kotaku</h3>\n<p>On February 8th, two days after Kotaku's accusatory article was published, another author of the news site wrote an article <a href=\"https://kotaku.com/the-flappy-bird-fiasco-1519938266\">&quot;The Flappy Bird Fiasco&quot;</a> apologizing to Nguyen Ha Dong:</p>\n<blockquote>\n<p>Nguyen also wound up receiving some negative attention because of the art in his game. That's where Kotaku comes into the story more than I'm comfortable with. And that's where I believe we owe Nguyen an apology. I'll say it now...</p>\n<p>Dong Nguyen, I'm sorry about what we wrote about your game's art. And I'm sorry if what we wrote contributed to any harassment you received about your game. Even if it didn't I wish we could do that one over.</p>\n<p>The author of that piece, Jason Schreier, has also asked to say the following...</p>\n<p>&quot;Over the past couple of days, I've spent a lot of time reading reactions and feedback to the article I published last week, and I've spent a lot of time regretting it. The post was rash, and hasty, and below my usual standards. To Kotaku I apologize for allowing that to happen. To Dong Nguyen, I apologize for my poorly-chosen words, and I hope that you find peace.&quot;</p>\n<p>Much has been made about that article we ran last Thursday, which originally was headlined &quot;Flappy Bird Is Making $50,000 A Day Off Ripped Art.&quot; The word &quot;ripped&quot; was too strong, and the article's author has come to regret it. I do, too, and wished I'd caught it. The headline's been changed since then.</p>\n<p>I wish that partially because I disagree with the opinion of the piece. I see Flappy Bird as being inspired by Mario art. I think it's as fair an inspiration as the many inspirations we've seen of classic Nintendo art in games from 3D Dot Game Heroes to Guacamelee to Braid. There's room for debate there, but that's where I stand.</p>\n</blockquote>\n<h2 id=\"some-other-misinformation\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#some-other-misinformation\" aria-hidden=\"true\">#</a> Some other misinformation</h2>\n<h3 id=\"impersonation-video\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#impersonation-video\" aria-hidden=\"true\">#</a> Impersonation video</h3>\n<p>During the time Flappy Bird was being taken down, the video <a href=\"https://youtu.be/vG6AvXDZ84g\">&quot;Flappy Bird - Message From Developer Dong Nguyen&quot;</a> appeared on Youtube, attracting a significant number of viewers:</p>\n<iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/vG6AvXDZ84g\" title=\"Flappy Bird - Message From Developer Dong Nguyen\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n<p>Ignoring the fact that the person in the video doesn't even look like Dong:</p>\n<figure class=\"w-full\">\n  <img class=\"w-full\" src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/nguyen_ha_dong.webp\" alt=\"Nguyễn Hà Đông\" />\n  <figcaption class=\"text-center\">Picture of Nguyen Ha Dong from a RollingStone's article</figcaption>\n</figure>\n<p>The title of the video is also very unusual compared to videos announcing serious issues on social media. The title is stated in the third person. The video content is just a reread of what Mr. Dong said on Twitter about removing Flappy Bird...</p>\n<h3 id=\"pewdiepie-made-faby-famous\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/16/#pewdiepie-made-faby-famous\" aria-hidden=\"true\">#</a> Pewdiepie made Faby famous?</h3>\n<p>Many people (including myself back then) thought that Flappy Bird was just a sinking game, that was luckily featured by the most famous YouTuber at that time - Pewdiepie. New gold spreads its wings and flies. The video <a href=\"https://youtu.be/lQz6xhlOt18\">&quot;FLAPPY BIRD - DONT PLAY THIS GAME!&quot;</a> posted on January 28 on the PewDiePie Youtube channel is believed by many netizens to be the direct cause of the Flappy Bird became famous.</p>\n<iframe class=\"aspect-video w-full\" src=\"https://www.youtube-nocookie.com/embed/lQz6xhlOt18\" title=\"FLAPPY BIRD - DONT PLAY THIS GAME!\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"></iframe>\n<p>Based on <a href=\"https://trends.google.com/trends/explore?date=2014-01-01%202014-04-01&amp;geo=US&amp;q=%2Fm%2F0_gzt9y\">Google Trends data from January to April of 2014 in America</a>:</p>\n<p><img src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/google_trends_27.png\" alt=\"Google trends 27/1\" />\n<img src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/google_trends_28.png\" alt=\"Google trends 28/1\" /></p>\n<p>Statistics show that the Flappy Bird keyword had already reached 9% of its popularity compared to its peak. And the keyword Flappy Bird did not have a sharp increase following Felix's video.</p>\n<p>Not only that, the data table below also shows that Flappy Bird has climbed to the top 1 on the App Store rankings since around January 15th:</p>\n<p><img src=\"https://codeberg.org/NNB/blog-images/raw/branch/main/16/store_rank.webp\" alt=\"Store rank\" /></p>\n<p>Not to mention, <a href=\"https://twitter.com/search?q=flappy%20bird%20until%3A2014-01-26%20since%3A2014-01-01&amp;f=live\">Flappy Bird was still mentioned a lot before the 28th on Twitter</a>, made popular thanks to everyone joking about Flappy Bird being too difficult and &quot;addictive&quot;. There is also a parody video of Twitter posts called <a href=\"https://youtu.be/0DMnVRU9G0Q\">&quot;FLAPPY BIRD RUINED MY LIFE&quot;</a> posted on January 25, released 2 days after Felix's video.</p>\n<p>It becomes even clearer when you actually watch the video of Felix playing Flappy Bird, <a href=\"https://youtu.be/lQz6xhlOt18?t=242\">starting at minute 4:02 in the video</a>.</p>\n<blockquote>\n<p>There's another game that you bro brought up...</p>\n</blockquote>\n<p>Later, he also said:</p>\n<blockquote>\n<p>I kind of know what it's about, but I never actually never played it myself.</p>\n</blockquote>\n<p>Flappy Bird wasn't chosen by Pewdiepie by dumb luck. It was chosen because it was a famous rage game and many of his fans wanted him to play. PewDiePie's video, more or less, made Flappy Bird even more famous. But it is not the main or direct cause, and certainly not the core reason why Flappy Bird became a phenomenon.</p>\n",
      "date_published": "2024-02-08T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/15/",
      "url": "https://nnb.codeberg.page/blog/en/posts/15/",
      "title": "CLI, TUI and GUI",
      "content_html": "<h2 id=\"definitions\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/15/#definitions\" aria-hidden=\"true\">#</a> Definitions</h2>\n<h3 id=\"gui\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/15/#gui\" aria-hidden=\"true\">#</a> GUI</h3>\n<p><strong>GUI</strong> or <strong>G</strong>raphical <strong>U</strong>ser <strong>I</strong>nterface is user interface type that allows users to interact through visual and graphic such as images, buttons, tabs, scroll bars... It's everywhere, it is like the default type of interface, the definition of user interface is self. All websites, smartphone interfaces, and the default file manager on your computer are all using GUI.</p>\n<p><a href=\"https://en.wikipedia.org/wiki/Graphical_user_interface\">(Read more on Wikipedia)</a></p>\n<h3 id=\"tui\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/15/#tui\" aria-hidden=\"true\">#</a> TUI</h3>\n<p><strong>TUI</strong> or <strong>T</strong>ext-based <strong>U</strong>ser <strong>I</strong>nterface is like GUI but instead of having visual and graphic, everything is displayed in text. Characters can be bold, italic, underlined, uppercase, lowercase, blinking, with any foreground or/and background color... But the text must always be mono characters (on grid). We will mainly see this type of interface on software run on terminal such as text editor, media player, task manager...</p>\n<p><a href=\"https://en.wikipedia.org/wiki/Text-based_user_interface\">(Read more on Wikipedia)</a></p>\n<h3 id=\"cli\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/15/#cli\" aria-hidden=\"true\">#</a> CLI</h3>\n<p><strong>CLI</strong> or <strong>C</strong>ommand <strong>L</strong>ine <strong>I</strong>nterface is an interface where the only way to interact is to write commands through a prompt and send it, the software will then return a results, and the user is allowed to type and send commands again.</p>\n<p>Software that <strong>uses</strong> CLI typically includes shells such as Bash, Zsh, Nushell... Some REPL (read-eval-print loop) for programing languages like Python, Ruby, ... And other tools like <a href=\"https://wiki.archlinux.org/title/NetworkManager#Usage\"><code>nmcli</code></a>, <a href=\"https://www.mankier.com/1/bc\"><code>bc</code></a>, <a href=\"https://github.com/printfn/fend\"><code>fend</code></a>, <a href=\"https://github.com/leo-arch/clifm\"><code>clifm</code></a>... But note that software that uses the CLI interface to display content inside it is <strong>not</strong> CLI software, but it is TUI.</p>\n<p>CLI software is software run as command inside a shell, for example <a href=\"https://www.mankier.com/1/ls\"><code>ls</code></a>, <a href=\"https://www.mankier.com/1/cp\"><code>cp</code></a>, <a href=\"https://www.mankier.com/1/mv\"><code>mv</code></a>, <a href=\"https://www.mankier.com/1/rm\"><code>rm</code></a>, <a href=\"https://www.mankier.com/1/cal\"><code>cal</code></a>, <a href=\"https://github.com/dylanaraps/neofetch\"><code>neofetch</code></a>, ... The general pattern of CLI softwares are like:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token builtin class-name\">command</span> parameter <span class=\"token parameter variable\">--flag</span></code></pre>\n<p><a href=\"https://en.wikipedia.org/wiki/Command-line_interface\">(Read more on Wikipedia)</a></p>\n<h2 id=\"cli-gui-and-tui\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/15/#cli-gui-and-tui\" aria-hidden=\"true\">#</a> CLI &gt; GUI (and TUI)</h2>\n<ul>\n<li>CLI seems difficult to use and learn at first. But once you get used to it, you can operate in shell really fast and flexible. Using CLI is like programming a simple software and runs it at the same time.</li>\n<li>Most CLI tool launch and process in a blink, reduce friction in your workflow.</li>\n<li>There is a giant library of cool and useful CLI tools that allow you to do things that few GUI/TUI software can do. Many tools give you the freedom to do all kinds of things with your computer. You can fix, change or break the entire operating system if you want.</li>\n<li>Using CLI is powerful in that we can connect separate software to work together by taking <code>stdout</code> (standard output) of a software and used it as <code>stdin</code> (standard input) for another software. We call this pipe/piping. Two or more software connected together in this way is called a pipeline.</li>\n</ul>\n<p>Here is an example of a pipeline (the <a href=\"https://www.mankier.com/1/echo\"><code>echo</code></a> command prints a string. <a href=\"https://www.mankier.com/1/rev\"><code>rev</code></a> reverses the input data. <a href=\"https://www.figlet.org/\"><code>figlet</code></a> turns strings into large ASCII letters. <a href=\"https://www.mankier.com/1/tee\"><code>tee</code></a> read from standard input and write to standard output and files, which a &quot;files&quot; can be a terminal output. Finally, the command <a href=\"https://getclipboard.app/\"><code>cb</code></a> copy input data to the clipboard):</p>\n<pre><code>$ echo '!dlroW ,olleH' | rev | figlet | tee /dev/tty | cb\n _   _      _ _         __        __         _     _ _\n| | | | ___| | | ___    \\ \\      / /__  _ __| | __| | |\n| |_| |/ _ \\ | |/ _ \\    \\ \\ /\\ / / _ \\| '__| |/ _` | |\n|  _  |  __/ | | (_) |    \\ V  V / (_) | |  | | (_| |_|\n|_| |_|\\___|_|_|\\___( )    \\_/\\_/ \\___/|_|  |_|\\__,_(_)\n                    |/\n[✔] Copied 336B\n</code></pre>\n",
      "date_published": "2023-12-30T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/14/",
      "url": "https://nnb.codeberg.page/blog/en/posts/14/",
      "title": "A rare $EDITOR hopping",
      "content_html": "<p>I never actually use 4chan before, but I found the greentext format to be quite interesting for story telling. So this time I will try writing a blog in this style, hope you enjoy!</p>\n<h2 id=\"emacs\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#emacs\" aria-hidden=\"true\">#</a> <a href=\"https://www.gnu.org/software/emacs\">Emacs</a></h2>\n  <p class=\"text-success\">\n    &gt; be me<br />\n    &gt; just switch from windows 10 to kde neon<br />\n    &gt; fall in love with it customizability<br />\n    &gt; discover <a class=\"text-success\" href=\"http://xahlee.info/emacs/emacs/emacs.html\">xah blog about emacs</a><br />\n    &gt; also pp say that its the most customizable text editor<br />\n    &gt; fitting with the linux spirit that i desire<br />\n    &gt; install it<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; emacs also come with a shitty tui and a clutter gui<br />\n    &gt; i minimize and customize the gui<br />\n    &gt; emacs is now as good as the default text editor that come with the de<br />\n    &gt; try out <a class=\"text-success\" href=\"https://www.spacemacs.org/\">spacemacs</a><br />\n    &gt; dont like it<br />\n    &gt; its slow and way more bloat<br />\n    &gt; decide to rice emacs from scratch<br />\n    &gt; drown myself in the <a class=\"text-success\" href=\"https://github.com/emacs-tw/awesome-emacs\">awesome emacs list</a><br />\n    &gt; install a LOT of packages to emacs<br />\n    &gt; spent months configuring emacs<br />\n    &gt; loving it<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; emacs have a ton of features<br />\n    &gt; too much features<br />\n    &gt; humongously bloat!<br />\n    &gt; not just ide level of bloat<br />\n    &gt; but os level of bloat<br />\n    &gt; even have a builtin file manager<br />\n    &gt; and tetris<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; slowly feel overwhelmed and exhausted in the emacs config rabbit hole<br />\n    &gt; still feel somewhat dissatisfied with the config...<br />\n  </p>\n<p>Learning about Emacs from XahLee's blogs, I discover <a href=\"http://xahlee.info/kbd/keyboarding.html\">Xah Keyboard Guide</a>, then of course learn about <a href=\"http://xahlee.info/emacs/emacs/ergonomic_emacs_keybinding.html\">XahLee's ErgoEmacs Keybinding</a> and <a href=\"https://ergoemacs.github.io/\">Ergoemacs-mode</a>, it's try to bind frequently used actions to easy to reach shortcut and use the commonly bound keys familiar to industry standard (e.g: <kbd class=\"kbd kbd-sm\">Ctrl</kbd> + <kbd class=\"kbd kbd-sm\">z</kbd> to undo, <kbd class=\"kbd kbd-sm\">Ctrl</kbd> + <kbd class=\"kbd kbd-sm\">s</kbd> to save). But it's heavy and breaks regularly, some of the binds I feel like missing or can be improved. So I decided to create <a href=\"https://github.com/NNBnh/.emacs.d/blob/main/key.el\">my own bindings</a>, unknowingly kickstart a length journey...</p>\n<p>Because I want a better Emacs keybinds instead of except it's legacy design, I couldn't stand the default keybinds and spent way too much time and energy to learn as much about Lips and Emacs's actions to config... That is the reason why I feel exhausted and dissatisfied with Emacs. And also at the time, I didn't know about <a href=\"https://github.com/doomemacs/doomemacs\">Doom Emacs</a>, an Emacs framework that doesn't bloat.</p>\n<h2 id=\"neovim\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#neovim\" aria-hidden=\"true\">#</a> <a href=\"https://neovim.io/\">NeoVim</a></h2>\n  <p class=\"text-success\">\n    &gt; watching some linux stuff on yt<br />\n    &gt; saw some cool hackerman-looking text editor<br />\n    &gt; its vim<br />\n    &gt; pp love vim<br />\n    &gt; specifically neovim<br />\n    &gt; try it out<br />\n    &gt; its very fast and light<br />\n    &gt; feel like a hackerman<br />\n    &gt; config nvim<br />\n    &gt; just week later<br />\n    &gt; i was able to config nvim to become a more ideal editor for me than emacs<br />\n  </p>\n<p>Emacs keybinds are weird, but Vi binds are otherworldly strange! Many keys feel redundant, some frequently used actions are place in awkward places...</p>\n<p>Vim introduce me to modal text editing. Simply put, it divides writing, editing and selecting and so on into separate modes, and so the user just need to press buttons to perform actions instead of holding down multiple keys combination. it took a few days to get used to, after that, ... [<strong>Enlightenment~</strong>], editing feel like dancing my fingers on the keyboard!</p>\n<p>Vi binds ecosystem is huge with a lot of popular tools implementing it in one way or the other, one that learn Vi keys will benefit a lot by it's ecosystem. I of course ignoring it and continue my own keybinds saga.</p>\n<p>This time I decide to turn the keybinds from my custom config into a big project, I create <a href=\"https://github.com/NNBnh/bkey-old\">Bkey</a> its a universal keybinds system design for almost all applications. By define each key on the keyboard with a meaning, the applications can bind their own set of shortcuts/actions to fit those meanings. And come with it: <a href=\"https://github.com/NNBnh/bkey-vim\">Bkey-Vim</a> a Bkey implement for Vim.</p>\n<h2 id=\"kakoune\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#kakoune\" aria-hidden=\"true\">#</a> <a href=\"https://kakoune.org/\">Kakoune</a></h2>\n  <p class=\"text-success\">\n    &gt; saw <a class=\"text-success\" href=\"https://youtu.be/sbfCSHhopT4\">a video about kakoune by dt</a><br />\n    &gt; skeptical at first<br />\n    &gt; then realize its genius design<br />\n    &gt; switch editor for the third time<br />\n    &gt; kakoune is extremely minimalistic<br />\n    &gt; and have better default<br />\n    &gt; plus easier to config than previous editor<br />\n    &gt; its build from the ground up with <a class=\"text-success\" href=\"https://kakoune.org/why-kakoune/why-kakoune.html\">its philosophy</a><br />\n    &gt; e.g: object followed by verb (like how thing should be)<br />\n    &gt; multiple selections is the best things ever introduced to text editors<br />\n    &gt; its easy to understand, fast, convenient, orthogonal, flexible and powerful<br />\n    &gt; boy i can never go back to those non multi selections editor every again<br />\n  </p>\n<p>When switching to Kakoune, I decide to overhaul the Bkey project, rebrand it to <a href=\"https://github.com/NNBnh/bmap\">Bmap</a> and create <a href=\"https://github.com/NNBnh/bmap.kak\">Bmap.kak</a> a Bmap implement for Kakoune.</p>\n<h2 id=\"other-tui-editors\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#other-tui-editors\" aria-hidden=\"true\">#</a> Other TUI editors</h2>\n  <p class=\"text-success\">\n    &gt; i also try out other tui editors later on:<br />\n  </p>\n<h3 id=\"helix\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#helix\" aria-hidden=\"true\">#</a> <a href=\"https://helix-editor.com/\">Helix</a></h3>\n  <p class=\"text-success\">\n    &gt; helix is like kakoune with builtin lsp and tree sitter<br />\n    &gt; written in rust<br />\n    &gt; blazingly fast<br />\n  </p>\n<p>I also wrote a lengthy features requests and changes to <a href=\"https://github.com/helix-editor/helix/issues/1179\">an issues on Helix's Github</a>, of course it got rejected.</p>\n<p>I try to make <a href=\"https://github.com/NNBnh/bmap-helix\">Bmap-Helix</a> (unfinished).</p>\n<h3 id=\"pepper\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#pepper\" aria-hidden=\"true\">#</a> <a href=\"https://vamolessa.itch.io/pepper\">Pepper</a></h3>\n  <p class=\"text-success\">\n    &gt; probably the best designed tui text editor that i know of<br />\n    &gt; its building up upon Kakoune philosophy<br />\n    &gt; but use caret style cursors<br />\n    &gt; (cursor is not a block in a characters but a thin line between two characters)<br />\n    &gt; like cursors on any other gui apps<br />\n    &gt; its keybinds actions are elegantly and convenient<br />\n    &gt; pepper is bloat free<br />\n    &gt; its doesnt having any feature that could instead be implemented by integrating an external tool<br />\n    &gt; its more minimal than nvim and helix<br />\n    &gt; but still have enough features (like lsp support) out of the box unlike kakoune<br />\n    &gt; the downside its although pepper is open source<br />\n    &gt; its not free<br />\n    &gt; at the time i try it still very buggy and unpolish<br />\n  </p>\n<p>And of course I ertend to make <a href=\"https://github.com/NNBnh/bmap-pepper\">Bmap-Pepper</a> (unfinished).</p>\n<h2 id=\"the-tiny-problem-with-tui-editor\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#the-tiny-problem-with-tui-editor\" aria-hidden=\"true\">#</a> The tiny problem with TUI editor</h2>\n<p>Normally when I'm moving around the file system in the shell, if I want to edit some files, I want to open the editor in a new window and leave the shell in the back, so latter I can do other things on the same path rather than replacing the current shell with the editor. I could write a script/alias/function to do that, but isn't a GUI editor like VScode already opened files in a new window by default?</p>\n<h2 id=\"vscode\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#vscode\" aria-hidden=\"true\">#</a> <a href=\"https://code.visualstudio.com/\">VScode</a></h2>\n  <p class=\"text-success\">\n    &gt; thinking about switching back to gui editor<br />\n    &gt; then a desperate thought appear<br />\n    &gt; maybe vscode<br />\n    &gt; the normie editor<br />\n    &gt; is the answer<br />\n    &gt; ...<br />\n    &gt; i have take a look at vscode in the past<br />\n    &gt; saw it have made a lot of right design decisions<br />\n    &gt; and used it as a standard to improve my other editor config<br />\n    &gt; maybe i should give it try<br />\n    &gt; ...<br />\n    &gt; install vscode<br />\n    &gt; probably the editor that come with the best default setting<br />\n    &gt; its not slow or heavy as pp said<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; its keybinds is industry standard<br />\n    &gt; multi selections in vscode is not as good as powerful as kakoune but still extremely good<br />\n    &gt; switching back to non modal editing feel a bit slow<br />\n    &gt; but for me its not a drop in productivity at all<br />\n    &gt; i still have my skill navigate with my trusty arrow keys<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; its have the best lps support<br />\n    &gt; and ton of other features<br />\n    &gt; yet none of it feel bloat<br />\n    &gt; vscode plugins ecosystem is the biggest<br />\n    &gt; easy to learn and config<br />\n    &gt; start spending more time to code than tweaking the editor<br />\n    &gt; seem like its the most popular editor for reasons<br />\n  </p>\n  <p class=\"text-success\">\n    &gt; while everyone share about how they switch from vscode to neovim and emacs<br />\n    &gt; i do this:<br />\n    &gt; emacs -&gt; neovim -&gt; kakoune -&gt; helix -&gt; pepper -&gt; vscode<br />\n    &gt; now that is a rare <code class=\"text-success\">$EDITOR</code> hopping<br />\n  </p>\n<h2 id=\"zed\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/14/#zed\" aria-hidden=\"true\">#</a> <a href=\"https://zed.dev/\">Zed</a></h2>\n<p><strong>Update!</strong> After writing this blog for a while, Zed was released.</p>\n<p>Zed is a GUI editor written in Rust. Compared to VScode, it is fast, minimalist, and at the same time has many built-in features that in VScode must be installed through extensions. Not only that, it also comes with Vim bindings! I don't care about Vim, what matters is that Zed has first-class modal editing that we can personalize, once again opening the door to the Bmap saga! That said, I'm pretty exhausted with making a massive system like Bmap, maybe I'll do something simpler...</p>\n",
      "date_published": "2023-12-25T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/13/",
      "url": "https://nnb.codeberg.page/blog/en/posts/13/",
      "title": "My ideal distro",
      "content_html": "<h2 id=\"why-linux-in-the-first-place\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/13/#why-linux-in-the-first-place\" aria-hidden=\"true\">#</a> Why Linux in the first place?</h2>\n<p>I choose Linux over Windows and MacOS because:</p>\n<ul>\n<li>It is fast, lightweight.</li>\n<li>It is <a href=\"https://wikipedia.org/wiki/Free_and_open-source_software\">FOSS</a>.</li>\n<li><a href=\"https://www.privacytools.io/os\">It's the most privacy desktop OS</a>.</li>\n<li>And most importantly it's customizability is endless.</li>\n</ul>\n<h2 id=\"base-distro\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/13/#base-distro\" aria-hidden=\"true\">#</a> Base Distro</h2>\n<p>My dotfiles is quite flexible, it can be easily adapted to almost any distro. But I still have preferences (in order): Arch-based &gt; Ubuntu-based &gt; Ubuntu/Debian-based &gt; other.</p>\n<p><a href=\"https://fedoraproject.org/\">Fedora</a> seems to be more stable and up-to-date than <a href=\"https://ubuntu.com/\">Ubuntu</a>, but it doesn't have packages that aren't strictly open source, a few can still be installed but it's annoying.</p>\n<p><a href=\"https://archlinux.org/\">Arch</a> has the most packages <em>if</em> including the AUR, which can sometimes be quite janky. Arch has a reputation for being easier to break than other distros, but I find all distros to break equally easy...</p>\n<p><a href=\"https://nixos.org/\">NixOS</a> is very competitive to Arch in terms of package quantity and quality. But I find Nix to be is quite janky after ricing it!</p>\n<h2 id=\"desktop-environment\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/13/#desktop-environment\" aria-hidden=\"true\">#</a> Desktop Environment</h2>\n<p>After using window manager for a while, I decided to go back to DE (detailed explanation <a href=\"https://nnb.codeberg.page/blog/en/posts/12/#5-maximalist\">here</a>) because I wanted to find an easy and stable experience that &quot;it just works&quot;.</p>\n<p>Some DEs like <a href=\"https://www.lxde.org/\">LXDE</a> and <a href=\"https://xfce.org/\">XFCE</a> are very light, too light in fact, it is not suitable for me because it is not as customizable as I want.</p>\n<p>DEs like <a href=\"https://elementary.io/\">Pantheon</a> and <a href=\"https://www.deepin.org/en/dde\">Deepin</a> have a pretty good out-of-the-box experience, but it's quite limited when it come to customization. I recommend this DE if you love it at first sight and have no need for customization.</p>\n<p><a href=\"https://www.kde.org/plasma-desktop\">KDE Plasma</a> is easy to customize out-of-the-box, from the simplest things to the most advanced. Plasma is easy to configure, suitable for Linux newbies who want to rice. KDE apps are also feature-rich (e.g: <a href=\"https://apps.kde.org/dolphin\">Dolphin</a>) but its interface is a bit cramped.</p>\n<p><a href=\"https://nnb.codeberg.page/blog/en/posts/13/www.gnome.org\">Gnome</a> design is very harmonious, consisted, minimalistic and elegant. Switching from Windows or other DE to Gnome initially feeling strange, but after a while you will understand the beauty of the design and a great workflow that Gnome brings to you. GNOME is actually no less than KDE but actually better when it comes to customization: Although GNOME is not officially supported, you can install <a href=\"https://extensions.gnome.org/\">extensions</a>. Gnome extensions are very diverse and extensive, it integrates well into DE. Gnome has extensions like <a href=\"https://extensions.gnome.org/extension/1287/unite\">Unite</a> while KDE can hardly config to do the same as convenience as Gnome.</p>\n<h2 id=\"other-requirements\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/13/#other-requirements\" aria-hidden=\"true\">#</a> Other requirements</h2>\n<ul>\n<li>Bloat-free: Do not preinstall software like games, maps, image/video editors or even web browsers. Don't put a bunch of software that some people might or might not like, let the users choose the software they want themselves. The bloatware may be pre-installed in the live-image but leave it as an unchecked option during the installation process.</li>\n<li>DE mustn't have any theming/branding presented, just the pure default theme DE.</li>\n<li>The distro should preinstalled:\n<ul>\n<li><a href=\"https://www.flatpak.org/\">Flatpak</a>.</li>\n<li><a href=\"https://wikipedia.org/wiki/CJK_characters\">A CJK font</a>.</li>\n<li>Necessary video codex and firmware.</li>\n<li>Archive format like <a href=\"https://7-zip.org/\">7-Zip</a>, <a href=\"https://www.rarlab.com/\">Rar</a>.</li>\n<li>CLI tools: <a href=\"https://git-scm.com/\">Git</a> and <a href=\"https://curl.se/\">Curl</a>.</li>\n<li>Vietnamese input method like <a href=\"https://www.unikey.org/en\">Unikey</a> or better.</li>\n<li>Tools to tweaks the DE:\n<ul>\n<li>If it's Gnome then it should have <a href=\"https://gitlab.gnome.org/GNOME/gnome-tweaks\">Gnome Tweaks</a> and <a href=\"https://wiki.gnome.org/Projects/GnomeShellIntegration\"><code>gnome-browser-connector</code></a> or <a href=\"https://mattjakeman.com/apps/extension-manager\">Extension Manager</a>.</li>\n<li>If KDE then it's <a href=\"https://store.kde.org/p/1005410\">Kvantum</a>.</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"my-ideal-distro\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/13/#my-ideal-distro\" aria-hidden=\"true\">#</a> My ideal distro</h2>\n<p><a href=\"https://vanillaos.org/\">Vanilla OS</a> is a immutable distro that allows users to install applications from any Linux distro from Arch, Fedora to NixOS. It checks a lot on the list but when I tried it early 2023, it didn't seem to be ready yet... Vanilla was very janky, it freezes when I wake it up after suspend...</p>\n<p><a href=\"https://blendos.co/\">Blend OS</a> is similar to vanilla but It's Arch-based, it's a bit bloater than Vanilla but also more stable. It also allows users to choose other DE than Gnome and Users can easily access CLI tools inside a container by write <code>command-name.container-name</code> in the terminal.</p>\n<p><a href=\"https://bazzite.gg/\">Bazzite</a> has all the goods of Blend OS, but it is <a href=\"https://fedoraproject.org/atomic-desktops\">Fedora Atomic Desktop</a>, and it is much more stable because it is based on Fedora. At the moment, I find Bazzite to be the closest thing to <a href=\"https://www.zdnet.com/article/why-dont-more-people-use-desktop-linux-i-have-a-theory-you-might-not-like\">&quot;the representative distro&quot;</a> because it meets all the criteria I set, except for a few:</p>\n<ul>\n<li>It's still a bit bloat, Firefox is pre-installed, but it is Flatpak and can be easily removed.</li>\n<li>It does not have a quality input method for Vietnamese.</li>\n</ul>\n",
      "date_published": "2023-08-12T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/12/",
      "url": "https://nnb.codeberg.page/blog/en/posts/12/",
      "title": "Five stages of minimalism rice",
      "content_html": "<p><a href=\"https://www.reddit.com/r/unixporn/comments/s0cccz/berry_ayudark_my_super_rice\"><img src=\"https://i.imgur.com/7DWRz1Z.webp\" alt=\"Berry Rice\" /></a></p>\n<p>While writing <a href=\"https://nnb.codeberg.page/blog/en/posts/9/\">Image viewer/media player for minimalist</a> about the five stages of rice image viewer, I realized that those five stages are not just about rice image viewer, it's about minimalism rice as a whole. So I wrote this blog post to dive into the five stages of minimalist rice.</p>\n<h2 id=\"1-normie\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#1-normie\" aria-hidden=\"true\">#</a> 1. Normie</h2>\n<p><a href=\"https://i.imgur.com/NTHZScu.webp\"><img src=\"https://i.imgur.com/NTHZScu.webp\" alt=\"KDE Rice\" /></a></p>\n<p>These newbies have just installed Linux, specifically Ubuntu or Ubuntu-based with a popular DE like Gnome or KDE. They installed some extensions, themes, icons and felt quite satisfied with their setup, thinking that they would never thinker with the OS ever again.</p>\n<h2 id=\"2-beginner\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#2-beginner\" aria-hidden=\"true\">#</a> 2. Beginner</h2>\n<p><a href=\"https://codeberg.org/NNB/dotfiles/releases/tag/v1.0.0\"><img src=\"https://user-images.githubusercontent.com/43980777/104730274-50495600-576c-11eb-9520-890cb45815d9.png\" alt=\"BSPWM Rice\" /></a></p>\n<p>After installing Linux and everything, that newbie must also watch a lot of Linux videos on Youtube, so his feed shows quite a lot of Linux Youtubers, he clicked on it and suddenly heard the three words &quot;I use Arch&quot; (four if you count &quot;BTW&quot;). They back up everything and distro-hop to Arch or an Arch-based distro. It wasn't long before they also discovered <a href=\"https://www.reddit.com/r/unixporn\">r/unixporn</a>, their eyes light up, they quickly install <a href=\"https://github.com/baskerville/bspwm\">BSPWM</a> + <a href=\"https://polybar.github.io/\">Polybar</a> or <a href=\"https://hyprland.org/\">Hyprland</a> + <a href=\"https://github.com/Alexays/Waybar\">Waybar</a> and spend 2-3 weeks to rice it.</p>\n<p>Using tiling WM is dedicated to following the keyboard workflow, but the keyboard workflow on Linux can't be perfect without the terminal.</p>\n<blockquote>\n<p><span class=\"font-mono\">GUI != Cool<br />\nTTY == Hackerman</span></p>\n</blockquote>\n<p>They started learning how to use the shell, replacing most GUI apps with TUI/CLI apps and replacing the main shell with anything but Bash. They rice their prompt with <a href=\"https://starship.rs/\">Starship</a>, installs <a href=\"https://github.com/sts10/rust-command-line-utilities#unix-to-rust-replacements-or-near-replacements\">Exa and other Rust-replacements CLI tool</a>. Wouldn't be surprised if they've spent months learning and configuring <a href=\"https://neovim.io/\">NeoVim</a> at this point.</p>\n<h2 id=\"3-minimalist\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#3-minimalist\" aria-hidden=\"true\">#</a> 3. Minimalist</h2>\n<p><a href=\"https://discord.com/channels/635612648934735892/1033210791320625243/1033339746463789096\"><img src=\"https://i.imgur.com/Sb9iZcz.webp\" alt=\"Cool Discord Rice\" /></a>\n<a href=\"https://codeberg.org/NNB/dotfiles/releases/tag/v3.3.0\"><img src=\"https://user-images.githubusercontent.com/43980777/172338839-482602d7-d57b-4152-a368-2333cf4c0d79.png\" alt=\"HerbstLuftWM Rice\" /></a></p>\n<h3 id=\"tiling-wm-is-bloat\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#tiling-wm-is-bloat\" aria-hidden=\"true\">#</a> Tiling WM is bloat</h3>\n<p>I used to use an advanced tiling WM but after I read <a href=\"http://xahlee.info/linux/why_tiling_window_manager_sucks.html\">this post</a>. When I first reading the post, I hate it, I think it is stupid, he just using the wrong way... But then I realize that my workflow rarely need tiling windows in a complex way to begin with:</p>\n<ul>\n<li>When I'm using GUI app with mouse, I always maximize the apps.</li>\n<li>When using the terminal or text editor, I just want to look at the focus window and see no value of looking at 3-4 terminal at the same time.</li>\n<li>Tiling 3-4 windows on the screen make everything cramped, the only advantage of this is to easily interact things between windows with a mouse which contradict with the keyboard workflow.</li>\n</ul>\n<p>Time to move to floating WM. The thing is that minimalist WMs like <a href=\"https://github.com/dylanaraps/sowm\">SOWM</a> and <a href=\"https://berrywm.org/\">Berry</a> are pretty janky (at least at the time of writing this) so go back to tiling WM we do, we just need to set the rule to make windows automatically float.</p>\n<h3 id=\"bar-is-also-bloat\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#bar-is-also-bloat\" aria-hidden=\"true\">#</a> Bar is also bloat</h3>\n<blockquote>\n<p><em>*Sniff sniff*</em> I smell bloat, and that smell comes from the bar. Switch to a lighter bar like <a href=\"https://github.com/LemonBoy/bar\">Lemonbar</a> or even <a href=\"https://sw.kovidgoyal.net/kitty/kittens/panel/#command-line-interface\">turn the terminal into bar</a> is unlikely to get rid of the stinky bloat smell.</p>\n<p>The problem is that it takes up precious space on my screen, a 16 to 24 pixel-wide space that stretches from one end to the other of the screen is <strong>wasted</strong> to display: the clock, workspaces, and some crappy information that I really don't need to check constantly. Unacceptable, throw the bar away!</p>\n<p>You can show the list of workspaces and the clock only when switching workspaces or using keyboard shortcuts to <a href=\"https://gist.github.com/NNBnh/5f6e601a6a82a6ed43b1959698758141?permalink_comment_id=3735888#gistcomment-3735888\">display it through a notification</a>.</p>\n<p>Or go the hardcore route and ditch it altogether, check the time on your watch, wall clock, or use the <code>date</code> command XD. Workspaces are really not necessary when I always maximize windows and rarely tile them anyway. Just use a workspace-less desktop, no need to config, no need to display.</p>\n</blockquote>\n<h2 id=\"4-extreme-minimalist\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#4-extreme-minimalist\" aria-hidden=\"true\">#</a> 4. Extreme Minimalist</h2>\n<p><a href=\"https://codeberg.org/NNB/dotfiles/releases/tag/v3.5.0\"><img src=\"https://user-images.githubusercontent.com/43980777/218121026-2d2ddb94-5105-4df8-a6a9-8ab632b69ce3.png\" alt=\"TTY rice w/ Zellij\" /></a></p>\n<p>WM... is Bloat. We can also get rid of WM and login manager altogether. Use full TTY from Linux Kernel and type the command to open GUI app... <a href=\"https://github.com/K4zoku/nowm\">NOWM</a> or <a href=\"https://git.disroot.org/root_informatica/wms\">[wms]</a> will make the experience less miserable without WM.</p>\n<p>Remember those TUI/CLI apps we installed at the beginner stage? We realize we don't need 80% of it, we would rather use the tools available in the POSIX standard to make the script more portable. Then we even removed the file manager!</p>\n<p>The shell prompt is now just &quot;<code>$</code>&quot;, <code>pwd</code> is the only torch that lights us the way in the file system.</p>\n<p>The rice is no longer minimalist, it has become a black hole. Few are brave enough to go beyond, but some legends continue, The few features that identifies them is that they do <a href=\"https://www.linuxfromscratch.org/lfs\">Linux From Scratch</a> and know what <a href=\"https://wikipedia.org/wiki/Linux_framebuffer\">Linux framebuffer</a> is.</p>\n<h2 id=\"5-maximalist\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/12/#5-maximalist\" aria-hidden=\"true\">#</a> 5. Maximalist</h2>\n<p><a href=\"https://github.com/Aylur/dotfiles/tree/gnome43\"><img src=\"https://raw.githubusercontent.com/Aylur/dotfiles/gnome43/assets/rose.png\" alt=\"Gnome Rice\" /></a></p>\n<p>After a tiresome period of extreme minimalist rice, they have a different view of minimalism. They realize that using DE is very minimal in terms of time and effort. To be honest, DE is not that bloat, It has some features that although we don't always use, but having it is still very convenient in some situation. &quot;And if I don't install or configure anything but just use the default stuff from the DE, the dotfiles will be a lot more minimal!&quot;</p>\n<p>And so they decided to go back to installing DE. But this time, with more experience and skill, their rice is better than ever. They even installed more fancy features, more personality, going against the previous minimalism... Finally they felt quite satisfied with their setup, thinking that they would never thinker with the OS ever again...</p>\n<hr />\n<p>Credit to <a href=\"https://github.com/K4zoku\">Kazoku</a> for the Rice images!</p>\n",
      "date_published": "2023-08-10T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/11/",
      "url": "https://nnb.codeberg.page/blog/en/posts/11/",
      "title": "Window&#39;s title",
      "content_html": "<p>Window's title is the most underrated aspect of a desktop when in fact it's very useful:</p>\n<ul>\n<li>It show information about the running programs in a standard way.</li>\n<li>It displays the titles of multiple windows which help us identify similar open applications (like when you open a bunch of text file and they're all look similar).</li>\n<li>It's easier for mouse user to interact with the window itself (not the application inside).</li>\n</ul>\n<p>But what is the best way to display window's title, let's take a look at some method.</p>\n<h2 id=\"key-terms\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#key-terms\" aria-hidden=\"true\">#</a> Key terms</h2>\n<ul>\n<li>Busy workspace: Workspace that have split layout container as it's first child.</li>\n<li>Tabs workspace: Workspace that have tabs layout container as it's first child. Because I turn <code>smart_gaps on</code> so a tabs workspace will not have gaps.</li>\n<li>The bar: (Usually called taskbar) will be refer as information bar.</li>\n</ul>\n<h2 id=\"legacy\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#legacy\" aria-hidden=\"true\">#</a> Legacy</h2>\n<p>This is the method that being used in Windows OS and most Linux's DE, it's display window's title both attach to the window itself and then show a list of windows on the information bar.</p>\n<table>\n<thead>\n<tr>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809472-7ff54480-75db-11eb-8bef-8cd640e1072a.png\" alt=\"bothBusy\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809474-808ddb00-75db-11eb-8dbb-35b9fa59878f.png\" alt=\"bothTab\" /></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"pro\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#pro\" aria-hidden=\"true\">#</a> Pro</h3>\n<ul>\n<li>This is a legacy design that most people get used to.</li>\n</ul>\n<h3 id=\"con\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#con\" aria-hidden=\"true\">#</a> Con</h3>\n<ul>\n<li>The design is too old, it's look outdated:\n<ul>\n<li>Display windows title in two place is redundant.</li>\n<li>And make the desktop cramped.</li>\n</ul>\n</li>\n</ul>\n<h3 id=\"fix\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#fix\" aria-hidden=\"true\">#</a> Fix</h3>\n<ul>\n<li>Just used other method...</li>\n</ul>\n<h2 id=\"detach\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#detach\" aria-hidden=\"true\">#</a> Detach</h2>\n<p>Only show a list of windows on the information bar.</p>\n<table>\n<thead>\n<tr>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809488-84b9f880-75db-11eb-8015-2729e907d094.png\" alt=\"taskBusy\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809489-85528f00-75db-11eb-9974-0956ba00ec1b.png\" alt=\"taskTab\" /></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"pro-1\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#pro-1\" aria-hidden=\"true\">#</a> Pro</h3>\n<ul>\n<li>This method give you the biggest screen real estate.</li>\n<li>And still shows you all the information: This is better than the <em>Attach method</em> in tabs workspace because it can even show additional information (workspaces and clock).</li>\n</ul>\n<h3 id=\"con-1\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#con-1\" aria-hidden=\"true\">#</a> Con</h3>\n<ul>\n<li>The problem is the way the information is presented, a list of title can show you how many windows and their name but not their location, so you end up confusing not knowing which title is correspond to which window... This defeat the whole purpose of display title for each window.</li>\n<li>You can't even tell if the container have tabs or not.</li>\n<li>It's hard for mouse user to interact with a window (drag and move window around).</li>\n<li>Those titles can take a lot of space in the information bar, space that can be used to display <code>CPU</code>, <code>MEM</code>, <code>DISK</code>, <code>TEMP</code>, <code>PLAYING</code>...</li>\n</ul>\n<h3 id=\"fix-1\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#fix-1\" aria-hidden=\"true\">#</a> Fix</h3>\n<ul>\n<li>&quot;you can't even tell if the container have tabs or not&quot;: You can make a container show title bar if it's has tabs but this is redundant to show title in two place.</li>\n</ul>\n<h2 id=\"attach\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#attach\" aria-hidden=\"true\">#</a> Attach</h2>\n<p>Show window's title attach to the window itself.</p>\n<table>\n<thead>\n<tr>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809490-85eb2580-75db-11eb-8900-7c81a2f22a28.png\" alt=\"titleBusy\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809492-8683bc00-75db-11eb-8fb7-8dbe4442787f.png\" alt=\"titleTab\" /></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"pro-2\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#pro-2\" aria-hidden=\"true\">#</a> Pro</h3>\n<ul>\n<li>Everything is simple and clear, you know exactly which title is correspond to which window.</li>\n<li>It's easy for mouse user to interact with a window (drag and move window around).</li>\n<li>If you have an information bar, this method leave more space to the information bar than <em>Detach method</em>.</li>\n</ul>\n<h3 id=\"con-2\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#con-2\" aria-hidden=\"true\">#</a> Con</h3>\n<ul>\n<li>This method take a bit more screen real estate than <em>Detach method</em> in specific conditions e.g: In the busy workspace, you can see most window's title bar just sit on the top of the screen but <code>win4</code>'s title bar (on image) take more space in the middle of the screen unlike <em>Detach method</em>.</li>\n<li>If you have an information bar, this method will take as much screen real estate as <em>legacy method</em> although that space is used more efficiently.</li>\n</ul>\n<h3 id=\"fix-2\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#fix-2\" aria-hidden=\"true\">#</a> Fix</h3>\n<ul>\n<li>About the screen real estate issue:\n<ul>\n<li>You can hide the information bar and only show it when holding the <kbd class=\"kbd\">Super</kbd> key like <a href=\"https://user-images.githubusercontent.com/43980777/108533634-c57bee00-730b-11eb-9b18-f17b3ca91ce6.mp4\">this</a>.</li>\n<li>Or only show it when user switch workspace.</li>\n<li>Make a hot corner for mouse user...</li>\n</ul>\n</li>\n<li>Auto hide the information bar can give user a clean and focus desktop but for some this is inconvenient. All of these problems can be solved through the last method.</li>\n</ul>\n<h2 id=\"dynamic\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#dynamic\" aria-hidden=\"true\">#</a> Dynamic</h2>\n<p>Show window's title attach to the window itself but with a twist:</p>\n<ul>\n<li>In tabs workspace, the tab show additional information on the left and right side of the tabs bar make the tabs workspace look like one in the <em>Detach method</em>.</li>\n<li>In busy workspace, additional information will keep being display on the same position on a bar.\n<ul>\n<li>The bar can automatically be transparent like how <a href=\"https://elementary.io/\">Elementary OS</a>'s bar work.</li>\n<li>If the desktop have gaps equal or bigger than the bar, information bar can be blended into the gap-part.</li>\n</ul>\n</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809479-82579e80-75db-11eb-94de-e3f790ce07e4.png\" alt=\"loveBusy\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809480-82f03500-75db-11eb-9302-94b3ab8c127b.png\" alt=\"loveTab\" /></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"pro-3\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#pro-3\" aria-hidden=\"true\">#</a> Pro</h3>\n<ul>\n<li>This solved the information bar problem, additional information (workspaces and clock) will always be visible and still make the tabs workspace compact like the <em>Detach method</em>.</li>\n<li>In a busy workspace, &quot;if the desktop have gaps equal or bigger than the bar, information bar can be blended into the gap-part&quot; which make the busy workspace as compact as in the <em>Attach method</em>.</li>\n</ul>\n<h3 id=\"con-3\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#con-3\" aria-hidden=\"true\">#</a> Con</h3>\n<table>\n<thead>\n<tr>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809476-81267180-75db-11eb-93d1-cb540b6fab66.png\" alt=\"hateBusy\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/43980777/108809478-81bf0800-75db-11eb-946a-6dd00a3b11fd.png\" alt=\"hateTab\" /></td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li>The title bar and information bar must be in the same direction to the window, if not (e.g: title bar attach to the top of the window but the information bar is on the bottom of the screen) the title will jump around when transition between busy workspace and tabs workspace. This will break the consistency of the desktop.</li>\n<li>If the desktop doesn't have gaps equal or bigger than the bar, the bar will be render fully in a busy workspace, and other than workspaces and clock, it display nothing... This bar took space on the desktop and used it inefficiency.</li>\n</ul>\n<h3 id=\"fix-3\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#fix-3\" aria-hidden=\"true\">#</a> Fix</h3>\n<ul>\n<li>Just use that empty space on the information bar to display more stuffs (<code>CPU</code>, <code>MEM</code>, <code>DISK</code>, <code>TEMP</code>, <code>PLAYING</code>...), then collapsed most of it to an arrow icon when switch to a tabs workspace.</li>\n</ul>\n<h2 id=\"conclusion\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/11/#conclusion\" aria-hidden=\"true\">#</a> Conclusion</h2>\n  <div class=\"overflow-x-auto whitespace-nowrap\">\n<table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Busy workspace</th>\n<th>Tabs workspace</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Legacy</strong></td>\n<td>Cramped</td>\n<td>Cramped</td>\n</tr>\n<tr>\n<td><strong>Detach</strong></td>\n<td>Confuse</td>\n<td>Best</td>\n</tr>\n<tr>\n<td><strong>Attach</strong></td>\n<td>Good</td>\n<td>Okay</td>\n</tr>\n<tr>\n<td><strong>Dynamic</strong></td>\n<td>Good (best if have gaps)</td>\n<td>Best</td>\n</tr>\n</tbody>\n</table>\n  </div>\n",
      "date_published": "2023-08-09T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/10/",
      "url": "https://nnb.codeberg.page/blog/en/posts/10/",
      "title": "Kera Desktop",
      "content_html": "<p>In 2021, I wrote a wiki article on my dotfiles repo called: <a href=\"https://github.com/NNBnh/dotfiles/wiki/wm\">Windows manager Utopia</a>. TL;DR it's the idea of using a web browser as a windows Manager. In it, I explain its benefits and features and theory how it might work...</p>\n<h2 id=\"the-project\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/10/#the-project\" aria-hidden=\"true\">#</a> The project</h2>\n<p>Then one day I saw <a href=\"https://www.reddit.com/r/unixporn/comments/14591h2/kera_desktop_forget_it_i_just_made_my_own_desktop\">this post on r/unixporn</a>:</p>\n<blockquote>\n<p><strong>[Kera Desktop] Forget it, I just made my own desktop environment</strong></p>\n</blockquote>\n<p><img src=\"https://i.imgur.com/Ad1YsFW.webp\" alt=\"Kera Desktop\" /></p>\n<p><a href=\"https://desktop.kerahq.com/\">Kera Desktop</a> is an independence DE, not only that, it also based on web technology The more I read the website of the project, the more I see that it has many great features and ideas as I expected!</p>\n<p>I don't even have anything to add here because <a href=\"https://desktop.kerahq.com/\">the project's website</a> has already done a good job explaining it, I recommend everyone to visit their website right away!</p>\n<h2 id=\"performance-skeptical\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/10/#performance-skeptical\" aria-hidden=\"true\">#</a> Performance skeptical</h2>\n<p>Many people when they hear &quot;web-based&quot; immediately doubt the project's performance, don't know if it will run on the Thinkpad with 0.5gb ram... I recommend you take a look at the <a href=\"https://desktop.kerahq.com/faq\">project's FAQ</a>. I guarantee it will answer most of your skeptical.</p>\n",
      "date_published": "2023-08-09T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/9/",
      "url": "https://nnb.codeberg.page/blog/en/posts/9/",
      "title": "Image viewer/media player for minimalist",
      "content_html": "<p>Here are my five stages of rice image viewer:</p>\n<h2 id=\"1-normie\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#1-normie\" aria-hidden=\"true\">#</a> 1. Normie</h2>\n<p>These newbies have just installed Linux and use the default image viewer that comes with the DE. Since it already there, why not use it, right?</p>\n<h2 id=\"2-beginner\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#2-beginner\" aria-hidden=\"true\">#</a> 2. Beginner</h2>\n<p>After installing Arch Linux (or Manjaro and pretending to use pure Arch) and setting up WM. The average r/unixporn enjoyer decided to install <a href=\"https://github.com/muennich/sxiv\">SXIV</a> after hearing that it was better than <a href=\"https://feh.finalrewind.org/\">FEH</a> from a Youtube video. But soon they realized that to configure SXIV, they had to edit the source code, and compile it themselves. Some continues to use it and adopts <a href=\"https://suckless.org/philosophy\">the Suckless philosophy</a>, others noticed the Suck**** inside of it and go on their journey to find a faster, lighter and easier to configure image viewer.</p>\n<h2 id=\"3-minimalist\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#3-minimalist\" aria-hidden=\"true\">#</a> 3. Minimalist</h2>\n<p><a href=\"https://mpv.io/\">MPV</a> is a media player that is as powerful as VLC but extremely lightweight/minimal. It's also secretly a good image viewer, use <a href=\"https://github.com/occivink/mpv-image-viewer\">MPV Image Viewer</a> to turn MPV into a perfect image viewer.</p>\n<p>Of course if you only use MPV as then it's pretty bloat, but if you already used it as a media player then it's definitely lighter than having a dedicated image viewer (also who have an image viewer but not have a media player, right?). You can think of an image as a video, but it has no sound and only have one frame, so use the media player to view image still satisfies the UNIX philosophy &quot;Programs that do one thing and do it well&quot;.</p>\n<h2 id=\"4-extreme-minimalist\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#4-extreme-minimalist\" aria-hidden=\"true\">#</a> 4. Extreme Minimalist</h2>\n<p>You can drag and drop media files into your web browser and it will play it. Realizing this, they quickly uninstall MPV and follow the path of suffering, path of extreme minimalism. There are a few formats it doesn't accept but it still be an acceptable solution... Or not, Using the browser can only view images in a very basic way, its experience is quite annoying. &quot;Have I gone too far?&quot;, &quot;Is this too minimalistic?&quot; they thought.</p>\n<h2 id=\"5-lazy\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#5-lazy\" aria-hidden=\"true\">#</a> 5. Lazy</h2>\n<p>After rice Linux - minimalist style for a while, they start to get tired and have a different view of minimalism. They realize that using DE is very minimal in terms of time and effort. To be honest, DE is not that bloat, It has some features that although we don't always use, but having it is still very convenient in some situation. And if I don't install or configure anything but just use the default stuff from the DE, the dotfiles will be a lot more minimal!</p>\n<p>And so they decided to go back to installing DE and use the default image viewer that comes with the DE. Since it already there, why not use it, right?</p>\n<h2 id=\"honorable-mention\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/9/#honorable-mention\" aria-hidden=\"true\">#</a> 📢 Honorable Mention</h2>\n<p><a href=\"https://imageglass.org/\">Image Glass</a>: It's only run on Windows but it's is the best image viewer for Windows, it's well design with enough feature to even do some light modification but not too bloat.</p>\n",
      "date_published": "2023-08-07T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/8/",
      "url": "https://nnb.codeberg.page/blog/en/posts/8/",
      "title": "My graveyard of projects",
      "content_html": "<p>List of projects I abandon. Some is finished, other left unfinished. But it's all pointless, or I don't feel it's useful to me anymore.</p>\n<h2 id=\"utilities\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#utilities\" aria-hidden=\"true\">#</a> Utilities</h2>\n<h3 id=\"superb-bootstrap\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#superb-bootstrap\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/superb-bootstrap\">Superb Bootstrap</a></h3>\n<ul>\n<li>Description: SuperB Bootstrap is a bootstrap-system/dotfiles-manager framework that can be installed with just one command on a new *NIX system installation. Its flagship feature it that it can pick and install packages from available package managers and can even install more package managers if necessary.</li>\n<li>Abandon reason: Although convenient, it's too unreliable. Also <a href=\"https://search.nixos.org/packages\">Nixpkgs</a>, <a href=\"https://brew.sh/\">Brew</a> and <a href=\"https://flatpak.org/\">Flatpak</a> exist. Even better: New distros like <a href=\"https://vanillaos.org/\">Vanilla OS</a> and <a href=\"https://blendos.co/\">Blend OS</a> can even allow you to install packages from multiple package managers from different distro.</li>\n</ul>\n<h3 id=\"coderun\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#coderun\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/coderun\">Coderun</a></h3>\n<ul>\n<li>Description: Code runner CLI that can run any languages. It recognizes the programming language from the file's extension and runs the file with the appropriate command.</li>\n<li>Abandon reason: You'd rather run the file by typing the appropriate command into the shell, which is more flexible and not much slower.</li>\n</ul>\n<h3 id=\"clipb-kak\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#clipb-kak\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/clipb.kak\">Clipb.kak</a></h3>\n<ul>\n<li>Description: Clipboard managers warper for Kakoune editor</li>\n<li>Abandon reason: Just install <a href=\"https://getclipboard.app/\">Clipboard</a> and add this to your <code>kakrc</code>:</li>\n</ul>\n<pre><code>hook -group 'clipboard' global WinCreate .* %{ evaluate-commands %sh{ printf '%s' 'set-register dquote %sh{ cb }' } }\nhook -group 'clipboard' global FocusIn   .* %{ evaluate-commands %sh{ printf '%s' 'set-register dquote %sh{ cb }' } }\nhook -group 'clipboard' global RegisterModified \\&quot; %{ nop %sh{ printf '%s' &quot;$clipboard&quot; | cb &amp; } }\n</code></pre>\n<h3 id=\"superb-mk\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#superb-mk\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/mk\">SuperB MK</a></h3>\n<ul>\n<li>Description: Its a files and folders creation tool inspired by <a href=\"https://github.com/tanrax/terminal-AdvancedNewFile\"><strong>Advanced New File</strong></a>.</li>\n<li>Abandon reason: I rarely find myself needing to create multiple folders and files with complex structure. If I need a template, I just init it's using a proper tool, or copy a template from some repo. Also, you can setup your text editor so that it automatically create parent directories if a file is opened on a path that does not exist (e.g: <code>mkparents</code> options in Micro editor).</li>\n</ul>\n<h3 id=\"superb-hr\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#superb-hr\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/hr\">SuperB HR</a></h3>\n<ul>\n<li>Description: Horizontal ruler for terminal.</li>\n<li>Abandon reason: This more of a shitpost than anything. Just put this into your shell config:</li>\n</ul>\n<pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function-name function\">hr</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">for</span> <span class=\"token for-or-select variable\">text</span> <span class=\"token keyword\">in</span> <span class=\"token string\">\"<span class=\"token variable\">${@<span class=\"token operator\">:-</span>─}</span>\"</span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">do</span>\n    <span class=\"token builtin class-name\">printf</span> <span class=\"token string\">'\\033[?7l%*s\\033[?7h'</span> <span class=\"token string\">\"<span class=\"token variable\">${<span class=\"token environment constant\">COLUMNS</span><span class=\"token operator\">:-</span>$(tput cols)}</span>\"</span> <span class=\"token operator\">|</span> <span class=\"token function\">sed</span> <span class=\"token parameter variable\">-e</span> <span class=\"token string\">\"s/ /<span class=\"token variable\">$text</span>/g\"</span>\n  <span class=\"token keyword\">done</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<h3 id=\"my-sed-script-collections\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#my-sed-script-collections\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/sed-collections\">My Sed script collections</a></h3>\n<ul>\n<li>Description: This is a collection of Sed scripts to help you filter text.</li>\n<li>Abandon reason: I never actually used it, I just made it for fun...</li>\n</ul>\n<h2 id=\"rice\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#rice\" aria-hidden=\"true\">#</a> Rice</h2>\n<h3 id=\"superb-st\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#superb-st\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/superb-st\">SuperB ST</a></h3>\n<ul>\n<li>Description: ST-base terminal with enough patches.</li>\n<li>Abandon reason: Even though it's fast and minimalist, it's quite janky and maintaining / building the binary myself is quite exhausting to me.</li>\n</ul>\n<h3 id=\"superb-ui\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#superb-ui\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/superb-ui\">SuperB UI</a></h3>\n<ul>\n<li>Description: It's a UI and colors management method that export the colors hex through environment variables so any program that can read environment variables can use it.</li>\n<li>Abandon reason: That's a bad idea... Environment variables are very slow, unstable, some applications/cases hard to read it. Use <a href=\"https://github.com/tinted-theming\">Tinted Theming</a>, <a href=\"https://github.com/deviantfero/wpgtk\">Wpgtk</a> or <a href=\"https://github.com/dylanaraps/pywal\">Pywal</a> instead.</li>\n</ul>\n<h3 id=\"diyship\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#diyship\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/info-mono/diyship\">DIYship</a></h3>\n<ul>\n<li>Description: DIYship is a cross-shell prompt framework that let you write your prompt with any programing language for any shell.</li>\n<li>Abandon reason: Except for creating a prompt that competes with <a href=\"https://starship.rs/\">Starship</a>, no souls need DIYship...</li>\n</ul>\n<h3 id=\"bmono\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#bmono\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/bmono\">Bmono</a></h3>\n<ul>\n<li>Description: My goal is to make a Iosevka font that fix the <a href=\"https://github.com/be5invis/Iosevka/issues/1326\">ligatures on Kitty bug</a> and come with some tiny tweak to make it slicker.</li>\n<li>Abandon reason: Now the <a href=\"https://github.com/be5invis/Iosevka/pull/1403\">Kitty bug had been fixed</a>, and you can tweak the font by using <a href=\"https://github.com/be5invis/Iosevka/issues/1376\">stylistic sets/character variants</a>, I no longer see the point of creating and maintaining a separate font.</li>\n</ul>\n<h3 id=\"da-one\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#da-one\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/da-one\">Da One</a></h3>\n<ul>\n<li>Description: A color scheme that vibrant and distinct but still maintain a pleasant harmony. It's design to work with terminal, meaning all accents tone have normal and bright colors.</li>\n<li>Abandon reason: <a href=\"https://github.com/catppuccin/catppuccin\">Catppuccin</a> exist and it did exactly that but better. I saw Catppuccin when I was making Da One, I could just stop right away but I think I could make a better color scheme than Catppuccin (nope).</li>\n</ul>\n<h2 id=\"other\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#other\" aria-hidden=\"true\">#</a> Other</h2>\n<h3 id=\"orange-markup-language\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/8/#orange-markup-language\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/NNBnh/orml\">Orange markup language</a></h3>\n<ul>\n<li>Description: Orange markup language is an &quot;original&quot; markup language inspired by <a href=\"https://pml-lang.dev/\">PML</a>, design to replace both Markdown and HTML.</li>\n<li>Abandon reason: After a while I start to realize that maybe we don't need another markdown language anymore:\n<ul>\n<li>For developer, HTML is the best choice because HTML's tags syntax is very clear.</li>\n<li>For causal writing usage, Markdown and AsciiDoc is good enough.</li>\n</ul>\n</li>\n</ul>\n",
      "date_published": "2023-08-06T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/7/",
      "url": "https://nnb.codeberg.page/blog/en/posts/7/",
      "title": "Ruby and Me",
      "content_html": "<p>Around February, after I posted <a href=\"https://codeberg.org/NNB/dotfiles/releases/tag/v3.5.0\">rice v3.5.0</a>, I promised to make a blog to explain how I use Ruby as a shell. Initially I want to explain it on an article, then it expanded into a website! Then a mountain of college work and internship job drop into my schedule... After all of that, I finally have time and energy to blogging again. So sorry and thank you everyone for waiting to follow my blog, I will try blogging more frequently!</p>\n<p>Back to Ruby. As mentioned, the website that I created is <a href=\"https://nnb.codeberg.page/ruby-on-shell\">Ruby on Shell</a> and you can read it right now. This blog post will focus on how I discovered the power of Ruby and the process by which I created Ruby on Shell.</p>\n<h2 id=\"how-i-get-to-know-ruby\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/7/#how-i-get-to-know-ruby\" aria-hidden=\"true\">#</a> How I get to know Ruby</h2>\n<p>I was a naive programmer back then, thinking that I should just master one programming language and use it for everything (and that language was Python, a very normie choice...). I used <a href=\"https://xon.sh/\">Xonsh</a> (in short, it is a fusion between Python and Bash) as my main shell for a while, its interactive experience is quite good but scripting on Xonsh is a bit annoying. Because of Python's off-side rule and list comprehension, it's hard for me to scripting as short as I'd like.</p>\n<p>I want a full-fledged programming language like Python, Perl or Lua but with good scripting features like <a href=\"https://www.nushell.sh/\">Nushell</a> or <a href=\"https://elv.sh/\">Elvish</a>.</p>\n<p>Then one day I saw this line on <a href=\"http://xahlee.info/comp/list_comprehension.html\">an article by Xah Lee about list comprehension</a>:</p>\n<blockquote>\n<pre class=\"language-rb\"><code class=\"language-rb\"><span class=\"token punctuation\">(</span><span class=\"token number\">0.</span><span class=\"token number\">.9</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>select<span class=\"token punctuation\">{</span><span class=\"token operator\">|</span>n<span class=\"token operator\">|</span> n<span class=\"token punctuation\">.</span>even<span class=\"token operator\">?</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">.</span>map<span class=\"token punctuation\">{</span><span class=\"token operator\">|</span>n<span class=\"token operator\">|</span> <span class=\"token number\">2</span><span class=\"token operator\">*</span>n<span class=\"token punctuation\">}</span></code></pre>\n<p>Note that this is not list comprehension, because it does not use a special syntax. But it captures the <code>map(f, filter(list,predicate))</code> in ruby style.</p>\n</blockquote>\n<p>I've seen Xah Lee mention Ruby a few times, but that's the first time I've read a Ruby code and understand what it does. Its syntax is very compact, I feel that I can script on this language easily. And I was correct, I've dived into <a href=\"https://nnb.codeberg.page/ruby-on-shell/#why-ruby\">why Ruby is a perfect choice for shell scripting in Ruby on Shell</a> so I won't repeat it again.</p>\n<p>Here are my few thoughts on Ruby before moving on to the next section:</p>\n<ul>\n<li>I have been peeking at Lua for a while now, I even found a shell similar to Xonsh but using Lua as the core (<a href=\"https://rosettea.github.io/Hilbish\">Hilbish</a>). But I don't really like Lua because even though it's fast, light, and simple... Its Syntax is still quite verbose and isn't easy to chain functions from left to right like Ruby or other shells.</li>\n<li>Currently, there is no language to easily run both Ruby and shell commands, so here is how I use Ruby in the terminal:\n<ul>\n<li>Use a POSIX shell as the main shell, and create a keybind in the shell to switch to Ruby for scripting.</li>\n<li>In Ruby there is a syntax to call shell commands easily (wrap the command with backticks) so just enjoy shell scripting.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"ruby-on-shell-how-it-s-made\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/7/#ruby-on-shell-how-it-s-made\" aria-hidden=\"true\">#</a> Ruby on Shell - How It's Made</h2>\n<p>Not difficult but very time consuming:</p>\n<ol>\n<li><strong>Make a list of standard CLI tools:</strong> I found it from the POSIX documentation, the list of tools in Toybox, and a few other sources. Then put it all together and go through the list to see what should and shouldn't be on the list.</li>\n<li><strong>Find the alternative in Ruby:</strong> Again go through everything on the list, find a similar function or library in Ruby and document it. Most of the time, I just need to add a link to an API, but some have to write a more detail instructions.</li>\n<li><strong>Build a proper website:</strong> Although this is the <em>hardest</em> part of the project, it only took me less than a week to finish the frontend... And about two weeks to writing the introduction.</li>\n</ol>\n<p>It was hard work, but it was worth it in the end. The process helped me increase my understanding of Ruby, plus now I have a pretty useful cheat-sheet.</p>\n<h2 id=\"the-future\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/7/#the-future\" aria-hidden=\"true\">#</a> The Future</h2>\n<p>I'm currently working on a project called <a href=\"https://codeberg.org/NNB/shell-on-ruby\">Shell on Ruby</a> to make scripting and using shell commands on Ruby more convenient.</p>\n<p>I'm also occasionally peeking <a href=\"https://crystal-lang.org/\">Crystal</a>, its syntax is ~90% similar to Ruby but faster and has some better design than Ruby, but scripting on it isn't as convenient.</p>\n<p>And that's all, I will continue my adventure on making a perfect scripting environment. See you in the next blogs.</p>\n",
      "date_published": "2023-08-06T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/6/",
      "url": "https://nnb.codeberg.page/blog/en/posts/6/",
      "title": "Tabs vs Apps",
      "content_html": "<p>If you want to access a platform like YouTube, Facebook, Discord, Messenger... and it requires an internet connection to access it, 95% of you don't need to download its app, just use it directly through the browser. Whether on a desktop or a mobile.</p>\n<h2 id=\"why-not-apps\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/6/#why-not-apps\" aria-hidden=\"true\">#</a> Why not apps?</h2>\n<ol>\n<li>It's bloat.</li>\n<li>App will have more access to user's personal data.</li>\n<li>You cannot open multiple tabs at the same time.</li>\n</ol>\n<h2 id=\"it-s-browser-tabs-good-enough\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/6/#it-s-browser-tabs-good-enough\" aria-hidden=\"true\">#</a> It's browser tabs good enough?</h2>\n<p>Yes, very good, in fact!</p>\n<h3 id=\"on-desktop\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/6/#on-desktop\" aria-hidden=\"true\">#</a> On Desktop</h3>\n<p>Most of us have been using web browsers to surf social media sites on the desktop. However, the same cannot be said for communication apps like Discord and Messenger. With these applications, people tend to download its own app because they think that they have to do so to use features such as notifications, toggle the mic when voice-call. But do you know that you can get these features even when using it on the web:</p>\n<ul>\n<li>All popular chat applications have a feature to show notifications on the web, but some (like Discord) don't show notifications by default, you just need to go to settings and enable it.</li>\n<li>Speaking of Discord, you can also toggle the mic with keyboard shortcuts like you use on Discord without downloading it: (<a href=\"https://superuser.com/questions/55598/super-key-to-pause-mute-mic-and-mute-speakers-in-windows\">Guide for setting up mic shortcuts on Windows with AutoHotKey</a>, <a href=\"https://askubuntu.com/questions/12100/command-to-mute-and-unmute-a-microphone\">Guide for doing the same on Linux</a>). That way you can toggle the mic when used with any app, for the whole system.</li>\n</ul>\n<h3 id=\"on-mobile\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/6/#on-mobile\" aria-hidden=\"true\">#</a> On mobile</h3>\n<p>Before 2014, most social medias website is unusable on mobile web browsers, often too laggy, and the interface are terrible compared to the apps. But over time, phones are now much faster now and websites have also significantly improved on browsers. Now day, accessing these platforms on a browser is even better than using apps:</p>\n<ul>\n<li>If you use Brave or Firefox with <a href=\"https://ublockorigin.com/\">uBlock Origin</a>, you have ad-blocker!</li>\n<li>You can leave YouTube playing on background.</li>\n<li>Opening links to other websites is more convenient than switching back and forth between the app and the browser.</li>\n<li>You can bookmark any websites and use a unified bookmark manager instead of using the save feature to save posts scattered in each social medias.</li>\n</ul>\n",
      "date_published": "2023-02-13T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/5/",
      "url": "https://nnb.codeberg.page/blog/en/posts/5/",
      "title": "Minimalist window manager&#39;s jobs",
      "content_html": "<p>This is a follow-up to <a href=\"https://nnb.codeberg.page/blog/en/posts/4\">&quot;Things to note when design a minimal CLI utility&quot;</a>, but this time it's about window manager.</p>\n<p><img src=\"https://user-images.githubusercontent.com/43980777/134518773-1862d6a4-3dea-4af7-a3aa-71cc79b91c71.png\" alt=\"Pixel Art\" /></p>\n<h2 id=\"configuration\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/5/#configuration\" aria-hidden=\"true\">#</a> Configuration</h2>\n<p>I have covered this in detail on <a href=\"https://nnb.codeberg.page/blog/en/posts/4\">my previous blog</a>, it just also applies to WM.</p>\n<h2 id=\"widgets\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/5/#widgets\" aria-hidden=\"true\">#</a> Widgets</h2>\n<p>Widgets like bar, menu don't need and shouldn't be built-in to the windows manager. Because there is already tools out there that handle these widgets far better\n(<a href=\"https://github.com/elkowar/eww\">EWW</a>, <a href=\"https://github.com/brndnmtthws/conky\">Conky</a>, <a href=\"https://wiki.archlinux.org/title/List_of_applications#Taskbars\">bars</a>, <a href=\"https://wiki.archlinux.org/title/List_of_applications#Application_launchers\">menus</a>).\nThe exception is if the WM has a whole widget's system like <a href=\"https://awesomewm.org/\">AwesomeWM</a> that can be used to config everything from wallpaper to window decorations.</p>\n<h2 id=\"wallpaper\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/5/#wallpaper\" aria-hidden=\"true\">#</a> Wallpaper</h2>\n<p>WM should not <em>go out of it's way</em> to handle wallpaper, leave it to the <a href=\"https://wiki.archlinux.org/title/List_of_applications/Other#Wallpaper_setters\">wallpaper setters</a>.</p>\n<h2 id=\"hotkeys\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/5/#hotkeys\" aria-hidden=\"true\">#</a> Hotkeys</h2>\n<p>The same go for hotkey, hotkey daemons exist!\n(<a href=\"https://github.com/baskerville/sxhkd\">SXHKD</a>, <a href=\"https://github.com/jtroo/kanata\">Kanata</a>, <a href=\"https://github.com/kmonad/kmonad\">KMonad</a>).\nThe only exception are to config mouse buttons (with mod keys) to focus, move and resize windows.</p>\n",
      "date_published": "2023-02-11T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/4/",
      "url": "https://nnb.codeberg.page/blog/en/posts/4/",
      "title": "Things to note when design a minimal CLI utility",
      "content_html": "<p><a href=\"https://wikipedia.org/wiki/Unix_philosophy\">The UNIX philosophy</a> is emphasized when it comes to designing CLI tools because it helps to tie together disparate tools into a unified TTY ecosystem. Each tool just <em>&quot;Do one thing and do it well&quot;</em>, which makes it possible for all tools to be harmoniously connected with each other. However, I still see many old and new CLI tools that have some redundant features. These features are included with the intention of making the tool more convenient to use, but users can already achieve it by piping to existed tools relatively convenient. Redundant features in a CLI tool only make the tool more cumbersome.</p>\n<h2 id=\"redirection\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/4/#redirection\" aria-hidden=\"true\">#</a> Redirection</h2>\n<p>If your tool works with strings and not specifically with files, it doesn't need flags to read files like <code>-f</code>, <code>--file</code>, <code>-i</code>, <code>--input</code>... Because it's unnecessary and makes your tool a bit more complicated. You should instead allow your tool to read <code>stdin</code>, this syntax can be used uniformly across tools and most shells have support for redirecting data from a file into tool:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">tool <span class=\"token operator\">&lt;</span> input.txt\n<span class=\"token function\">cat</span> input.txt <span class=\"token operator\">|</span> tool\n<span class=\"token function\">cat</span> input1.txt input2.txt <span class=\"token operator\">|</span> tool</code></pre>\n<p>Similar to reading files, most shells have support for redirecting output to files:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">tool <span class=\"token operator\">></span> output.txt\ntool <span class=\"token operator\">>></span> output.txt\ntool <span class=\"token operator\">|</span> <span class=\"token function\">tee</span> output1.txt output2.txt\ntool <span class=\"token operator\">&lt;</span> input.txt <span class=\"token operator\">>></span> output.txt</code></pre>\n<h2 id=\"clipboard\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/4/#clipboard\" aria-hidden=\"true\">#</a> Clipboard</h2>\n<p>Your CLI tool should not have the features to get or set to the clipboard because people will use your tool in all kinds of environments, and you can't support every clipboard manager out there. But if users want your tool to interact with the clipboard, they'll be more likely to pipe it to the clipboard manager they're using:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">cb <span class=\"token operator\">|</span> tool\ntool <span class=\"token operator\">|</span> cb</code></pre>\n<h2 id=\"configuration\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/4/#configuration\" aria-hidden=\"true\">#</a> Configuration</h2>\n<p>Don't invent a new format or new language just to config your tool:</p>\n<ul>\n<li>If the config file only stores values, use JSON, TOML, YAML or even <a href=\"https://kdl.dev/\">KDL</a>. INI is fine, but it has some limitations and is not implement consistently. Using a common format is of course better for both developers and users. Dotfiles management tools like Home Manager can also work with these formats easier.</li>\n<li>If it needs scripting, create a CLI interface so any language can call it. Or create a library / API for Lua, Python, Ruby... Don't create a dedicate programming language just to config your tool because that language will most likely limited, janky and just never be as good or as flexible as some proper languages.</li>\n</ul>\n<h2 id=\"colored-outputs\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/4/#colored-outputs\" aria-hidden=\"true\">#</a> Colored outputs</h2>\n<p>If your tool supports color rendering, please use <a href=\"https://wikipedia.org/wiki/ANSI_escape_code\">3-bit and 4-bit color</a> as the default! I know TTY's default color isn't pleasant, but most terminal users use themes, and when they use themes they want all programs to display with the colors in the theme, not a bunch of random colors. A lot of CLI tools out there that don't follow this and choose to use Monokai, Gruvbox or their own (often really odd) colors!</p>\n<h2 id=\"further-readings\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/4/#further-readings\" aria-hidden=\"true\">#</a> Further readings</h2>\n<p>I highly recommend everyone to read <a href=\"https://clig.dev/\">Command Line Interface Guidelines</a>, the article is not only have a guide but also gives philosophy when designing CLI.</p>\n",
      "date_published": "2023-02-02T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/3/",
      "url": "https://nnb.codeberg.page/blog/en/posts/3/",
      "title": "Pick a web browser",
      "content_html": "<h2 id=\"it-s-time-to-ditch-chrome\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/3/#it-s-time-to-ditch-chrome\" aria-hidden=\"true\">#</a> It's time to ditch Chrome</h2>\n<p>Chrome is currently the most popular browser, but that doesn't mean it's the best. It used to be the best, but now there are many of other browsers that are better in every way, from features to security (Chrome collects a lot of user data!).</p>\n<p>If you are using Windows, using Edge is better than Chrome because Edge is also a Chromium-based browser, and it comes pre-installed anyway. Although, I wouldn't recommend using Edge because there are so many better options like:</p>\n<h2 id=\"firefox\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/3/#firefox\" aria-hidden=\"true\">#</a> <a href=\"https://www.mozilla.org/firefox/new\">Firefox</a></h2>\n<p><img src=\"https://i.imgur.com/8HtSanJ.webp\" alt=\"Firefox\" /></p>\n<p>Firefox-based browsers <a href=\"https://www.privacytools.io/private-browser\">are the most secure</a>. But more importantly, Firefox is extremely customizable:</p>\n<ul>\n<li>Unlike most Chromium-based browsers, Firefox allows you to change the position of toolbar buttons.</li>\n<li>You can easily create themes with <a href=\"https://color.firefox.com/\">Firefox Color</a>.</li>\n<li>If you want to change more advanced stuff, you can <a href=\"https://www.reddit.com/r/firefox/wiki/userchrome\">customize Firefox with CSS</a>.</li>\n<li>Or use one of <a href=\"https://github.com/topics/userchrome\">the beautiful themes developed by the community</a>.</li>\n</ul>\n<h2 id=\"zen\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/3/#zen\" aria-hidden=\"true\">#</a> <a href=\"https://www.zen-browser.app/\">Zen</a></h2>\n<p><img src=\"https://i.imgur.com/xowuE7A.webp\" alt=\"Zen\" /></p>\n<p>Zen is also Firefox-based but has been heavily modified to increase performance, privacy and security. It has good default settings, without the need to spend a lot of time configuring like Firefox. Zen takes all the best of Firefox's customizability and x10s it: It has vertical tabs like <a href=\"https://arc.net/\">Arc</a>, and accent colors... But Zen's killer feature, the thing that makes Zen stand out from other browsers, is its theme system:</p>\n<p>In Firefox, users can personalize it further by writing CSS to intervene deeply in the browser, these are quite complicated to install, but then it is still quite limited. In contrast, Zen has a JS and CSS theme system built into the browser, even allowing users to upload themes to <a href=\"https://www.zen-browser.app/themes\">Zen's theme store</a> so that anyone who wants it can download and use it. Furthermore, Zen also allows users to use multiple themes at the same time, each of which can customize individual components so that the user can choose and combine them to create the best experience for themselves.</p>\n<h2 id=\"some-chromium-based-alternatives\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/3/#some-chromium-based-alternatives\" aria-hidden=\"true\">#</a> Some Chromium-based alternatives</h2>\n<p>Zen is the best in many ways, but it's not a Chromium-based browser. This can be seen as a good thing because it breaks the monopoly that Chrome and Google hold in the web browser market. But some still need to use Chromium-based browser for a variety of reasons.</p>\n<h3 id=\"brave\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/3/#brave\" aria-hidden=\"true\">#</a> <a href=\"https://brave.com/\">Brave</a></h3>\n<p><img src=\"https://i.imgur.com/ba0rBQ6.webp\" alt=\"Firefox\" /></p>\n<p>Brave is <a href=\"https://www.privacytools.io/private-browser\">second in terms of privacy and security</a>, but its default setting is the most secure (it has a built-in ad-blocker), which is great for those who want security without the hassle of setting up.</p>\n<p>Unlike Firefox on mobile, Brave on mobile is also very secure, using the same browser on all platforms is also very convenient for data synchronization, open tabs, etc.</p>\n<!--\n\n### [Vivaldi](https://vivaldi.com)\n\n![Vivaldi](https://i.imgur.com/Qs9lalF.webp)\n\n\n  Although it's not very private and secure, Vivaldi is the most feature-rich browser (kitchen-sink included!). It has calendar, email, contacts, split screen feature... Vivaldi is also very easy to customize, although it is not as advanced as Firefox CSS, it has a lot of customizations available out of the box.\n\n  At first, I quite liked it. But later on, I found it cumbersome. And although it is pretty customizable, I still do not find it as satisfying as to customize Firefox.\n\n\n-->\n",
      "date_published": "2023-01-30T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/2/",
      "url": "https://nnb.codeberg.page/blog/en/posts/2/",
      "title": "Become a Hackerman",
      "content_html": "<p>As a programmer, you need to master a lot of skills, one of which is to look cool. Here are some TTY tools that can help turn you into a <em>Hackerman</em>.</p>\n<h2 id=\"cool-retro-term\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#cool-retro-term\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/Swordfish90/cool-retro-term\">Cool Retro Term</a></h2>\n<blockquote>\n<p>cool-retro-term is a terminal emulator which mimics the look and feel of the old cathode tube screens. It has been designed to be eye-candy, customizable, and reasonably lightweight.</p>\n</blockquote>\n<div class=\"sm:hidden\">\n<p><img src=\"https://user-images.githubusercontent.com/121322/32070717-16708784-ba42-11e7-8572-a8fcc10d7f7d.gif\" alt=\"Default Amber Cool Retro Term\" />\n<img src=\"https://user-images.githubusercontent.com/121322/32070715-163a1c94-ba42-11e7-80bb-41fbf10fc634.gif\" alt=\"Default Green Cool Retro &gt; Term\" /></p>\n</div>\n<div class=\"hidden sm:block\">\n<table>\n<thead>\n<tr>\n<th>&gt; Default Amber</th>\n<th>$ Default Green</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><img src=\"https://user-images.githubusercontent.com/121322/32070717-16708784-ba42-11e7-8572-a8fcc10d7f7d.gif\" alt=\"Default Amber Cool Retro Term\" /></td>\n<td><img src=\"https://user-images.githubusercontent.com/121322/32070715-163a1c94-ba42-11e7-80bb-41fbf10fc634.gif\" alt=\"Default Green Cool Retro &gt; Term\" /></td>\n</tr>\n</tbody>\n</table>\n</div>\n<h2 id=\"edex-ui\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#edex-ui\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/GitSquared/edex-ui\">eDEX-UI</a></h2>\n<blockquote>\n<p>A cross-platform, customizable science fiction terminal emulator with advanced monitoring &amp; touchscreen support.</p>\n</blockquote>\n<p><img src=\"https://raw.githubusercontent.com/GitSquared/edex-ui/master/media/screenshot_default.png\" alt=\"eDEX-UI\" /></p>\n<h2 id=\"tdfgo\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#tdfgo\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/digitallyserviced/tdfgo\">Tdfgo</a></h2>\n<blockquote>\n<p><a href=\"https://en.wikipedia.org/wiki/TheDraw\">TheDraw</a> font parser and console text renderer.</p>\n</blockquote>\n<p><img src=\"https://raw.githubusercontent.com/digitallyserviced/tdfgo/main/assets/tdfgocast.gif\" alt=\"Tdfgocast\" />\n<img src=\"https://raw.githubusercontent.com/digitallyserviced/tdfgo/main/assets/tdfgo-print-user.png\" alt=\"Tdfgo print user\" /></p>\n<p>Some alternative:\n<a href=\"http://www.figlet.org/\">FIGlet</a>, <a href=\"http://caca.zoy.org/wiki/toilet\">TOIlet</a>\nwith\n<a href=\"https://github.com/xero/figlet-fonts\">Xero's fonts collection</a>.</p>\n<h2 id=\"btop\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#btop\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/aristocratos/btop\">Btop</a></h2>\n<blockquote>\n<p>Resource monitor that shows usage and stats for processor, memory, disks, network and processes.</p>\n</blockquote>\n<p><img src=\"https://i.imgur.com/eDvgKsI.webp\" alt=\"Btop\" /></p>\n<h2 id=\"unimatrix\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#unimatrix\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/will8211/unimatrix\">Unimatrix</a></h2>\n<blockquote>\n<p>Python script to simulate the display from &quot;The Matrix&quot; in terminal.</p>\n</blockquote>\n<p><img src=\"https://i.imgur.com/BHeqwCQ.webp\" alt=\"Unimatrix\" /></p>\n<p>Some alternative:\n<a href=\"https://github.com/abishekvashok/cmatrix\">Cmatrix</a>, <a href=\"https://github.com/st3w/neo\">Neo</a>.</p>\n<h2 id=\"no-more-secrets\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#no-more-secrets\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/bartobri/no-more-secrets\">No more secrets</a></h2>\n<blockquote>\n<p>This project provides a command line tool called <code>nms</code> that recreates the famous data decryption effect seen on screen in the 1992 hacker movie Sneakers. For reference, you can see this effect at 0:35 in <a href=\"https://youtu.be/F5bAa6gFvLs?t=35\">this movie clip</a>.</p>\n</blockquote>\n<p><img src=\"https://www.brianbarto.info/static/nms/nms.gif\" alt=\"Screenshot\" /></p>\n<blockquote>\n<p>Also included in this project is a program called <code>sneakers</code> that recreates what we see in the above movie clip.</p>\n</blockquote>\n<p><img src=\"https://www.brianbarto.info/static/nms/sneakers.gif\" alt=\"Screenshot\" /></p>\n<h2 id=\"genact\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#genact\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/svenstaro/genact\">Genact</a></h2>\n<blockquote>\n<p>Pretend to be busy or waiting for your computer when you should actually be doing real work! Impress people with your insane multitasking skills. Just open a few instances of <code>genact</code> and watch the show. <code>genact</code> has multiple scenes that pretend to be doing something exciting or useful when in reality nothing is happening at all.</p>\n</blockquote>\n<p><img src=\"https://raw.githubusercontent.com/svenstaro/genact/master/gifs/cc.gif\" alt=\"CC\" />\n<img src=\"https://raw.githubusercontent.com/svenstaro/genact/master/gifs/memdump.gif\" alt=\"Memdump\" />\n<img src=\"https://raw.githubusercontent.com/svenstaro/genact/master/gifs/cargo.gif\" alt=\"Cargo\" /></p>\n<h2 id=\"awesome-console-services\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#awesome-console-services\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/chubin/awesome-console-services\">Awesome console services</a></h2>\n<blockquote>\n<p>A curated list of awesome console services (reachable via HTTP, HTTPS and other network protocols).</p>\n</blockquote>\n<p>Notables are:</p>\n<h3 id=\"mapscii\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#mapscii\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/rastapasta/mapscii\">MapSCII</a></h3>\n<blockquote>\n<p>MapSCII is a Braille &amp; ASCII world map renderer for your console.</p>\n</blockquote>\n<script id=\"asciicast-117813\" src=\"https://asciinema.org/a/117813.js\" async=\"\"></script>\n<p>Try it out:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\">telnet mapscii.me</code></pre>\n<h3 id=\"rickrollrc\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/2/#rickrollrc\" aria-hidden=\"true\">#</a> <a href=\"https://github.com/keroserene/rickrollrc\">Rickrollrc</a></h3>\n<blockquote>\n<p>Bash script which <a href=\"http://en.wikipedia.org/wiki/Rickrolling\">rickrolls</a> your terminal by playing Rick Astley’s “Never Gonna Give You Up”.</p>\n</blockquote>\n<p><img src=\"http://i.imgur.com/yDLaZna.png\" alt=\"rickroll in mac\" /></p>\n<p>To start rickrollin’ immediately:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">curl</span> <span class=\"token parameter variable\">-sL</span> https://raw.githubusercontent.com/keroserene/rickrollrc/master/roll.sh <span class=\"token operator\">|</span> <span class=\"token function\">bash</span></code></pre>\n<p>Here is the clandestine command you can give to your friends 😈:</p>\n<pre class=\"language-sh\"><code class=\"language-sh\"><span class=\"token function\">curl</span> <span class=\"token parameter variable\">-sL</span> http://bit.ly/10hA8iC <span class=\"token operator\">|</span> <span class=\"token function\">bash</span></code></pre>\n",
      "date_published": "2023-01-24T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/1/",
      "url": "https://nnb.codeberg.page/blog/en/posts/1/",
      "title": "Setting from TTY",
      "content_html": "<p>This is just a small list of guides on system configuration from the command line instead of the bloated config app that come with the desktop environment.</p>\n<h2 id=\"system\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/1/#system\" aria-hidden=\"true\">#</a> 🖥️ System</h2>\n<ul>\n<li><a href=\"https://wiki.archlinux.org/title/Users_and_groups\">Users</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/System_time\">Time</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Locale\">Locale</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Power_management\">Power</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Partitioning\">Partition</a></li>\n</ul>\n<h2 id=\"connect\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/1/#connect\" aria-hidden=\"true\">#</a> 📶 Connect</h2>\n<ul>\n<li><a href=\"https://wiki.archlinux.org/title/NetworkManager\">Wifi</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Network_configuration\">Network</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Bluetooth\">Bluetooth</a></li>\n</ul>\n<h2 id=\"devices\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/1/#devices\" aria-hidden=\"true\">#</a> 🖱️ Devices</h2>\n<ul>\n<li><a href=\"https://cheat.sh/pactl\">Sound</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Category:Keyboard_configuration\">Keyboard</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Category:Mice\">Mouse</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Touchpad_Synaptics\">Touchpad</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Wacom_tablet\">Tablet</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Touchscreen\">Touchscreen</a></li>\n<li><a href=\"https://wiki.archlinux.org/title/Xrandr\">Display</a> (<a href=\"https://sr.ht/~emersion/wlr-randr\">for Wayland</a>)</li>\n</ul>\n",
      "date_published": "2023-01-23T00:00:00Z"
    }
    ,
    {
      "id": "https://nnb.codeberg.page/blog/en/posts/0/",
      "url": "https://nnb.codeberg.page/blog/en/posts/0/",
      "title": "*First post!",
      "content_html": "<h2 id=\"hello-world\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/0/#hello-world\" aria-hidden=\"true\">#</a> Hello, World!</h2>\n<p>Welcome to my blog! This isn't really my first time blogging, I've written some articles on my <a href=\"https://github.com/NNBnh/dotfiles/wiki\">Đotfiles</a>'s wiki before, but NNBlog is a fresh start. In the coming month, I will copy most articles from the Dotfiles to this site.</p>\n<h2 id=\"the-technical\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/0/#the-technical\" aria-hidden=\"true\">#</a> The technical</h2>\n<p>Before that, I wanted to show off a little bit about the technical side of this site. This is a static website generated using <a href=\"https://www.11ty.dev/\">11ty (Eleventy)</a>. 11ty is a light, simple and convenient JS framework. Its most important feature is that it allows the us to write the page in <a href=\"https://wikipedia.org/wiki/Markdown\">Markdown</a>. Not only that, it also has many features such as creating a table of contents, tag manager... This is quite ideal for a tinker like me.</p>\n<p>I also use <a href=\"https://daisyui.com/\">DaisyUI</a> for styling and <a href=\"https://alpinejs.dev/\">Alpine.js</a> for a bit of interactive. Although, Alpine.js is a bit overkill at the moment (the only thing that needs it is an image hover effect on the homepage):</p>\n<p><img src=\"https://i.imgur.com/KZ93WrH.webp\" alt=\"Hover effect\" /></p>\n<p>But in the future I can give a small interactive parts in some articles.</p>\n<h2 id=\"support-multi-language\" tabindex=\"-1\"><a class=\"link-mono\" href=\"https://nnb.codeberg.page/blog/en/posts/0/#support-multi-language\" aria-hidden=\"true\">#</a> Support multi-language</h2>\n<p>Before, I only wrote in English because I wrote it on Github Wiki. But as you can see in the right corner of the Navbar there is a button to change to Vietnamese, I had blog in both English and Vietnamese! From now on, I will write in my native language first, then translate it to English. I'm quite confident about my English listening/reading skill, but I'm still a writing newbie, so <a href=\"https://languagetool.org/\">LanguageTool</a> (an open source grammar checker) has become an indispensable tool for me.</p>\n<p>The common way to support multi-language in 11ty is to split it into two directories <code>en/</code> and <code>vi/</code>, the same post has separate files of each language on each directory. That method is fine, but I want more flexibility in managing and reusing the elements of the article. So I let 11ty paginate each Markdown file into two pages in English (with <code>lang = 'en'</code>) and Vietnamese (with <code>lang = 'vi'</code>) so I can write in a single file like this:</p>\n<pre class=\"language-liquid\"><code class=\"language-liquid\">---\ntitle:\n  en: \"*First post!\"\n  vi: Blog post \"đầu tiên\"!\ndescription:\n  en: Made with 11ty\n  vi: Khai bút đầu năm bằng 11ty\ntags:\n  - update\n  - web_dev\ndate: 2023-01-22\nimage: https://images.unsplash.com/photo-1674240660273-a3496c4604fd\n---\n\n<span class=\"token liquid language-liquid\"><span class=\"token delimiter punctuation\">{%</span> <span class=\"token keyword\">if</span> lang <span class=\"token operator\">==</span> <span class=\"token string\">'vi'</span> <span class=\"token delimiter punctuation\">%}</span></span>\n  Xin chào!\n<span class=\"token liquid language-liquid\"><span class=\"token delimiter punctuation\">{%</span> <span class=\"token keyword\">else</span> <span class=\"token delimiter punctuation\">%}</span></span>\n  Hello!\n<span class=\"token liquid language-liquid\"><span class=\"token delimiter punctuation\">{%</span> <span class=\"token keyword\">endif</span> <span class=\"token delimiter punctuation\">%}</span></span></code></pre>\n<p>That's all folks, I hope you all look forward to reading my next blog posts, bye!</p>\n",
      "date_published": "2023-01-22T00:00:00Z"
    }
    
  ]
}
