-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrss.xml
More file actions
6216 lines (5988 loc) · 430 KB
/
rss.xml
File metadata and controls
6216 lines (5988 loc) · 430 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title><![CDATA[Fezcodex]]></title>
<description><![CDATA[A personal blog by Ahmed Samil Bulbul]]></description>
<link>https://fezcode.com</link>
<image>
<url>https://fezcode.com/logo512.png</url>
<title>Fezcodex</title>
<link>https://fezcode.com</link>
</image>
<generator>RSS for Node</generator>
<lastBuildDate>Sun, 11 Jan 2026 19:28:35 GMT</lastBuildDate>
<atom:link href="https://fezcode.com/rss.xml" rel="self" type="application/rss+xml"/>
<pubDate>Sun, 11 Jan 2026 19:28:34 GMT</pubDate>
<copyright><![CDATA[2026 Ahmed Samil Bulbul]]></copyright>
<language><![CDATA[en]]></language>
<managingEditor><![CDATA[samil.bulbul@gmail.com (Ahmed Samil Bulbul)]]></managingEditor>
<webMaster><![CDATA[samil.bulbul@gmail.com (Ahmed Samil Bulbul)]]></webMaster>
<ttl>60</ttl>
<item>
<title><![CDATA[Implementing Drag and Drop in React without Libraries]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/implementing-drag-and-drop-in-react</link>
<guid isPermaLink="false">https://fezcode.com/blog/implementing-drag-and-drop-in-react</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Sat, 10 Jan 2026 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>When building <strong>Tier Forge</strong>, I needed a flexible way to move items between the "pool" and various "tiers". While libraries like <code>react-beautiful-dnd</code> or <code>dnd-kit</code> are excellent, sometimes you just want full control without the overhead.</p>
<p><a href="https://fezcode.com/blog/implementing-drag-and-drop-in-react">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Fixing gh-pages: Resolving spawn ENAMETOOLONG]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/gh-pages-enametoolong-fix</link>
<guid isPermaLink="false">https://fezcode.com/blog/gh-pages-enametoolong-fix</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h1>Resolving <code>spawn ENAMETOOLONG</code> in <code>gh-pages</code> Deployment</h1>
<p><a href="https://fezcode.com/blog/gh-pages-enametoolong-fix">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Git Cheatsheet: From Basics to Time Travel]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/git-cheatsheet-gist</link>
<guid isPermaLink="false">https://fezcode.com/blog/git-cheatsheet-gist</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h1>Git Cheatsheet: From Basics to Time Travel</h1>
<p><a href="https://fezcode.com/blog/git-cheatsheet-gist">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Aether: Cyberpunk Audio Interface]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/aether-music-player</link>
<guid isPermaLink="false">https://fezcode.com/blog/aether-music-player</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h1>Aether: The Cyberpunk Music Player</h1>
<p>I've just deployed <strong>Aether</strong>, a new cloud-based music player for Fezcodex.</p>
<p><img src="/images/apps/aether.png" alt="Aether Music Player"></p>
<h2>Overview</h2>
<p>Aether isn't just a music player; it's an atmospheric audio interface designed to immerse you in the soundscape of the site. It features:</p>
<ul>
<li><strong>Cyberpunk Aesthetic:</strong> A high-contrast, terminal-inspired interface with CRT scanlines, glitch effects, and a generative art background that reacts to the music.</li>
<li><strong>Persistent Playback:</strong> A tiny, "cyber deck" style player docks to the bottom of your screen, allowing you to browse the site without interrupting your tunes.</li>
<li><strong>Generative Art:</strong> If a track lacks cover art, the system generates a unique visual signature based on the track's title.</li>
</ul>
<p>Check it out here: <a href="/apps/aether">Aether Music Player</a></p>
<p>Enjoy the vibes.</p>
<p><a href="https://fezcode.com/blog/aether-music-player">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[5 Ways to Pass Arguments in a URL (Beyond the Basic Query)]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/5-ways-to-pass-arguments-in-a-url</link>
<guid isPermaLink="false">https://fezcode.com/blog/5-ways-to-pass-arguments-in-a-url</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>When building web applications or designing APIs, understanding how to transfer data is crucial. While <strong>Query Parameters</strong> (the bits after the <code>?</code>) are the most common method, there are four other fundamental ways to pass arguments to a server via a URL or its associated HTTP request.</p>
<p>Here is a quick reference guide to the five main argument passing mechanisms:</p>
<h2>1. Query Parameters</h2>
<ul>
<li><strong>Location:</strong> Appears in the URL after a <strong>?</strong> (question mark) and separated by <strong>&</strong> (ampersand) symbols.</li>
<li><strong>Purpose:</strong> Used for <strong>optional</strong> parameters such as filtering, sorting, searching, or pagination controls.</li>
<li><strong>Characteristics:</strong> Data is highly visible (in the URL, server logs, and browser history). It is typically used with <strong>GET</strong> requests.</li>
<li><strong>Example:</strong> <code>https://example.com/products?**category=1&sort=price**</code></li>
</ul>
<h2>2. Path Parameters</h2>
<ul>
<li><strong>Location:</strong> Directly integrated into the URL's path structure.</li>
<li><strong>Purpose:</strong> Used to uniquely <strong>identify a specific resource</strong> or define a hierarchical location.</li>
<li><strong>Characteristics:</strong> Essential for defining clear, clean, and meaningful URLs, especially in RESTful API design.</li>
<li><strong>Example:</strong> <code>https://example.com/users/**123**</code> or <code>https://example.com/books/**sci-fi**/dune</code></li>
</ul>
<h2>3. Header Parameters</h2>
<ul>
<li><strong>Location:</strong> Contained within the <strong>HTTP Request Header</strong>, invisible in the URL.</li>
<li><strong>Purpose:</strong> Used for <strong>metadata</strong> about the request, such as authentication (e.g., API keys, tokens), content type, and language preferences.</li>
<li><strong>Characteristics:</strong> Offers better security for sensitive, non-data payload information compared to Query Parameters, as it doesn't appear in the URL.</li>
<li><strong>Example:</strong> <code>Header: **Authorization: Bearer token**</code> or <code>Header: **Content-Type: application/json**</code></li>
</ul>
<h2>4. Fragment Identifier Arguments</h2>
<ul>
<li><strong>Location:</strong> Appears at the very end of the URL after a <strong>#</strong> (hash symbol).</li>
<li><strong>Purpose:</strong> Used for client-side functionality, like navigating to a specific section (anchor) on a page or managing application state in Single Page Applications (SPAs).</li>
<li><strong>Characteristics:</strong> The browser <strong>does NOT send this part to the server</strong>; it is client-side only. It can still be used to pass data to the front-end application.</li>
<li><strong>Example:</strong> <code>https://example.com/page**#section-name**</code></li>
</ul>
<h2>5. Request Body Arguments</h2>
<ul>
<li><strong>Location:</strong> Contained within the <strong>body</strong> (payload) of the HTTP request, invisible in the URL.</li>
<li><strong>Purpose:</strong> Used for sending large data payloads when creating or updating resources (e.g., submitting a complex form, uploading a file, or sending a JSON object).</li>
<li><strong>Characteristics:</strong> The primary method for data submission using <strong>POST, PUT, or PATCH</strong> HTTP methods. It is an HTTP request argument, not a true URL argument, and it is secure from URL exposure.</li>
<li><strong>Example:</strong> <em>(Data like a user object in JSON format is sent in the hidden body payload.)</em></li>
</ul>
<hr>
<h2>Conclusion</h2>
<p>By strategically selecting among Query, Path, Header, Fragment, or Body arguments, developers can ensure their data is transferred efficiently and securely, leading to a robust and scalable application architecture.</p>
<p><a href="https://fezcode.com/blog/5-ways-to-pass-arguments-in-a-url">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Quick Renaming .js to .jsx for React]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/renaming-js-to-jsx-gist</link>
<guid isPermaLink="false">https://fezcode.com/blog/renaming-js-to-jsx-gist</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h2>The Command (PowerShell)</h2>
<p>I ran this specific script in your terminal. It uses "piping" (<code>|</code>) to pass the result of one command to the next, like a bucket brigade.</p>
<pre><code class="language-powershell">Get-ChildItem -Path src -Recurse -Filter *.js |
Where-Object { $_.Name -notin @('index.js', 'reportWebVitals.js', 'setupTests.js') } |
ForEach-Object {
if (Select-String -Pattern "<[a-zA-Z]" -Path $_.FullName -Quiet) {
Write-Host "Renaming $($_.Name) to .jsx";
Rename-Item -LiteralPath $_.FullName -NewName ($_.Name -replace '\.js$', '.jsx')
}
}
</code></pre>
<h3>Deep Dive: Commands & Arguments</h3>
<p>Here is exactly what every part of that spell does:</p>
<p><strong>1. Finding the files</strong>
<code>Get-ChildItem -Path src -Recurse -Filter *.js</code></p>
<ul>
<li><code>Get-ChildItem</code>: The standard command to list files (like <code>ls</code> or <code>dir</code>).</li>
<li><code>-Path src</code>: We only look inside the <code>src</code> folder.</li>
<li><code>-Recurse</code>: We dig deep into every subfolder, not just the top level.</li>
<li><code>-Filter *.js</code>: We ignore everything except files ending in <code>.js</code>.</li>
</ul>
<p><strong>2. Filtering the list</strong>
<code>Where-Object { $_.Name -notin @(...) }</code></p>
<ul>
<li><code>Where-Object</code>: Acts like a bouncer; only lets items through that match the condition.</li>
<li><code>$_</code>: Represents the "current file" being checked.</li>
<li><code>-notin</code>: The condition operator. We are saying "The name must NOT be in this list".</li>
<li><code>@('index.js', ...)</code>: The list of system files we want to skip (leave as <code>.js</code>).</li>
</ul>
<p><strong>3. Processing each file</strong>
<code>ForEach-Object { ... }</code></p>
<ul>
<li><code>ForEach-Object</code>: Runs the code block inside <code>{ ... }</code> for every single file that made it past the filter.</li>
</ul>
<p><strong>4. Checking for React Code (JSX)</strong>
<code>if (Select-String -Pattern "<[a-zA-Z]" -Path $_.FullName -Quiet)</code></p>
<ul>
<li><code>Select-String</code>: Searches for text inside a file (like <code>grep</code>).</li>
<li><code>-Pattern "<[a-zA-Z]"</code>: A Regex pattern. It looks for a <code><</code> followed by a letter. This catches HTML tags like <code><div></code> or React components like <code><App></code>.</li>
<li><code>-Path $_.FullName</code>: The full path to the file we are currently reading.</li>
<li><code>-Quiet</code>: Important! This tells the command "Don't print the matching text, just tell me True or False."</li>
</ul>
<p><strong>5. Renaming the file</strong>
<code>Rename-Item -LiteralPath $_.FullName -NewName (...)</code></p>
<ul>
<li><code>Rename-Item</code>: The command to change a file's name.</li>
<li><code>-LiteralPath $_.FullName</code>: We use the full path to ensure we target the exact right file.</li>
<li><code>-NewName ($_.Name -replace '\.js$', '.jsx')</code>: We calculate the new name by taking the old name and swapping the ending <code>.js</code> with <code>.jsx</code>.</li>
</ul>
<p><strong>The Result</strong></p>
<p>Now your code editor knows exactly which files contain UI components. You'll get better autocomplete, better color highlighting, and generally a much happier development experience.</p>
<p><a href="https://fezcode.com/blog/renaming-js-to-jsx-gist">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Corrupted Blood Incident: When a Glitch Taught Us About Pandemics]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/corrupted-blood-incident</link>
<guid isPermaLink="false">https://fezcode.com/blog/corrupted-blood-incident</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p><em>Okay, gather 'round</em>, fellow nerds and accidental epidemiologists.
I need to talk about something that happened in <em>World of Warcraft</em> back in 2005.
It's called the <strong>Corrupted Blood incident</strong>, and it's basically the coolest (and most terrifying) accidental science experiment in gaming history.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/vj-mz5piYYY?si=RlcxH-t2Q7-2bYIJ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h2>ELI5: What the Heck Happened?</h2>
<p>Imagine you're playing a game, right? You and your 19 closest friends decide to go punch a giant blood god named <strong>Hakkar the Soulflayer</strong> in the face. This raid boss has a nasty spell called "Corrupted Blood."</p>
<p>Here's how it worked:</p>
<ol>
<li><strong>You catch it:</strong> It drains your health. Fast.</li>
<li><strong>It spreads:</strong> If you stand near anyone else, they catch it too. Like a super-flu.</li>
<li><strong>It's meant for the boss room:</strong> The disease was programmed to disappear when you died or left the dungeon.</li>
</ol>
<p><strong>BUT HERE'S THE GLITCH.</strong></p>
<p>Hunter pets (animals that players control) could catch the disease. If a player dismissed their pet while it was sick, the game "froze" the pet's state.
When they summoned the pet back in a major city (like Ironforge or Orgrimmar), the pet came back... <em>still sick</em>.</p>
<p><em>Boom. Patient Zero.</em></p>
<h2>The Virtual Apocalypse</h2>
<p>Suddenly, high-level players' pets were nuking entire cities. Low-level players (newbies) were dropping dead instantly just by walking past the auction house.
High-level players were scrambling to keep themselves alive, healing frantically.</p>
<p>It was chaos.</p>
<ul>
<li><strong>The Cities:</strong> Zones of death. Skeletons everywhere.</li>
<li><strong>The Players:</strong> Panic. Some fled to the wilderness (social distancing!). Some deliberately spread it (trolls/bioterrorists). Healers tried to set up triage centers.</li>
<li><strong>Blizzard (The Devs):</strong> They tried quarantines. Failed. They tried warnings. Failed. Eventually, they had to do a hard server reset to scrub the disease from existence.</li>
</ul>
<h2>Why Real Scientists Cared</h2>
<p>Here's the wild part. Real-world epidemiologists (the doctors who study diseases) looked at this and went, <em>"Holy crap, this is better than our computer models."</em></p>
<p>Usually, scientific models assume people act rationally. "If there is a plague, people will stay home." But in <em>WoW</em>, people did <strong>human</strong> things:</p>
<ul>
<li><strong>Curiosity:</strong> "What's happening over there?" -> <em>Dies.</em></li>
<li><strong>Malice:</strong> "Imma go infect the newbies lol." -> <em>Spreads plague.</em></li>
<li><strong>Altruism:</strong> "I'll heal you!" -> <em>Gets infected, spreads it further.</em></li>
</ul>
<p>This accidental glitch provided a perfect, unscripted look at human behavior during a crisis. It showed how fast things spread when people don't follow rules,
how asymptomatic carriers (pets/high-level players) can destroy vulnerable populations (low-level players), and how hard it is to contain stupidity.</p>
<h2>The GDC Legacy</h2>
<p>This wasn't just a "remember when" moment. It became a serious case study. At <strong>GDC (Game Developers Conference)</strong>,
this incident is often cited as a prime example of emergent gameplay and complex systems gone wrong (or right, depending on your view).</p>
<p>It taught developers that players will <em>always</em> find a way to break containment.
It taught scientists that "Gamer Behavior" might actually be a decent proxy for "Human Panic."</p>
<h2>The Rant</h2>
<p>It drives me crazy that we had this perfect simulation in 2005, and when 2020 rolled around, we saw the <em>exact same behaviors</em> IRL.
The deniers, the spreaders, the people fleeing to the countryside. We didn't learn! We leveled up, but we didn't put any points into Wisdom!</p>
<p><strong>TL;DR:</strong> A coding bug in a fantasy game predicted modern pandemic behavior better than some government models.
Hakkar the Soulflayer is the ultimate teacher. Wash your hands, dismiss your pets responsibly, and for the love of Azeroth, stop standing in the fire.</p>
<p><a href="https://fezcode.com/blog/corrupted-blood-incident">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Building the Knowledge Graph: Visualizing Fezcodex in 3D]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/building-the-knowledge-graph</link>
<guid isPermaLink="false">https://fezcode.com/blog/building-the-knowledge-graph</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>The idea was simple: Fezcodex is growing. With hundreds of blog posts, apps, and project logs, a standard list or grid view just wasn't cutting it anymore. I wanted a way to visualize the <em>connections</em> between everything. To see the "brain" of the website.</p>
<p>Enter the <strong>Knowledge Graph Visualization Protocol</strong>.</p>
<h2>The Concept</h2>
<p>I wanted a 3D, interactive network graph where:</p>
<ul>
<li><strong>Nodes</strong> represent content (Blog Posts, Apps, Projects).</li>
<li><strong>Links</strong> represent relationships (Shared tags, Categories).</li>
<li><strong>Interaction</strong> allows users to fly through the data and navigate to content.</li>
</ul>
<p>It needed to feel like a "cyberspace" visualization from a sci-fi movie—immersive, dark, and slightly chaotic but organized.</p>
<h2>The Tech Stack</h2>
<ul>
<li><strong>React</strong>: The core framework.</li>
<li><strong>react-force-graph-3d</strong>: The heavy lifter. This library uses WebGL (via Three.js) to render force-directed graphs with great performance.</li>
<li><strong>PIML</strong>: My custom markup language for parsing project data.</li>
<li><strong>Tailwind CSS</strong>: For the overlay UI and brutalist styling.</li>
</ul>
<h2>Implementation Details</h2>
<h3>1. Data Extraction (<code>graphDataManager.js</code>)</h3>
<p>The first challenge was aggregating data from three different sources:</p>
<ul>
<li><code>posts.json</code>: A static JSON file containing blog metadata.</li>
<li><code>apps.json</code>: A structured list of all the mini-apps.</li>
<li><code>projects.piml</code>: A custom file format for my project portfolio.</li>
</ul>
<p>I created a utility function <code>fetchGraphData</code> that pulls all three.</p>
<pre><code class="language-javascript">export const fetchGraphData = async () => {
const nodes = [];
const links = [];
const tagMap = new Map();
// ... fetching logic ...
</code></pre>
<p>For each item, I created a <strong>primary node</strong>. Then, I looked at its <code>tags</code>, <code>category</code>, or <code>technologies</code>. For every tag found, I created a <strong>tag node</strong> (if it didn't exist) and created a <strong>link</strong> between the item and the tag.</p>
<p>This automatically creates clusters. If five posts are tagged "React", they all link to the "React" tag node, pulling them together in the 3D space.</p>
<h3>2. The 3D Component (<code>KnowledgeGraphPage.js</code>)</h3>
<p>I used <code><ForceGraph3D></code> to render the data.</p>
<pre><code class="language-jsx"><ForceGraph3D
ref={fgRef}
graphData={graphData}
backgroundColor="#050505"
nodeLabel="name"
nodeColor="color"
onNodeClick={handleNodeClick}
// ...
/>
</code></pre>
<h3>3. Camera Controls</h3>
<p>The "cool factor" comes from the camera movement. When you click a node, I didn't want a hard jump. I wanted a smooth flight.</p>
<pre><code class="language-javascript"> const handleNodeClick = useCallback((node) => {
// Calculate a position slightly "outside" the node
const distance = 40;
const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z);
if (fgRef.current) {
fgRef.current.cameraPosition(
{ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new pos
node, // lookAt
3000 // ms duration
);
}
}, []);
</code></pre>
<p>This calculates a vector from the center (0,0,0) to the node, extends it by a fixed distance, and moves the camera there while focusing on the node.</p>
<h2>Challenges</h2>
<ul>
<li><strong>PIML Parsing</strong>: My custom language parser needed to be robust enough to handle the varying structures of the <code>projects.piml</code> file.</li>
<li><strong>Performance</strong>: Rendering hundreds of text labels in 3D can be heavy. I kept the UI minimal and only showing detailed info on hover.</li>
<li><strong>Theme</strong>: Matching the "Brutalist/Cyberpunk" aesthetic required careful tuning of node colors (Emerald for Apps, Red for Posts) and link opacity.</li>
</ul>
<h2>The Result</h2>
<p>The result is a living, breathing map of Fezcodex. It reveals patterns I didn't explicitly plan—like the massive cluster around "React" or the isolated islands of specific game experiments. It's not just a navigation tool; it's a piece of generative art powered by my own work.</p>
<p>Go check it out at <code>/graph</code> and fly through the system.</p>
<p><a href="https://fezcode.com/blog/building-the-knowledge-graph">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Routing Revolution: SSG, BrowserRouter, and the SEO Fix]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/routing-revolution-ssg-and-seo</link>
<guid isPermaLink="false">https://fezcode.com/blog/routing-revolution-ssg-and-seo</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h1>Routing Revolution: SSG, BrowserRouter, and the SEO Fix</h1>
<p>For a long time, Fezcodex lived behind the "Hash Gap." If you looked at your address bar, you’d see that familiar <code>/#/</code> slicing through every URL. While functional, this was the primary reason social media thumbnails were failing and search engines were only seeing the home page.</p>
<p>Today, I’ve completed a total migration to <strong><a href="/vocab/spa">BrowserRouter</a></strong> combined with <strong><a href="/vocab/ssg">SSG (Static Site Generation)</a></strong>. Here is the technical breakdown of why this was necessary and how it works.</p>
<h2>The Problem: The Hash Black Hole</h2>
<p>We originally used <code>HashRouter</code> because Fezcodex is hosted on GitHub Pages. Since GitHub Pages is a static file host, it doesn't know how to handle a request for <code>/apps/markdown-table-formatter</code>. It looks for a folder named <code>apps</code> and an <code>index.html</code> inside it. When it doesn't find them, it throws a 404.</p>
<p><code>HashRouter</code> solved this by putting everything after the <code>#</code>. The server ignores the hash, always serves the root <code>index.html</code>, and React handles the rest. </p>
<p><strong>The SEO Cost:</strong> Most <strong><a href="/vocab/crawler">crawlers</a></strong> (Twitter, Facebook, Discord) do not execute JavaScript and ignore the hash entirely. To them, every single link you shared looked like <code>fezcode.com/</code>—resulting in generic "Fezcodex - Personal Blog" thumbnails instead of page-specific content.</p>
<h2>The Solution Part 1: BrowserRouter</h2>
<p>I switched the core engine from <code>HashRouter</code> to <code>BrowserRouter</code>. This gives us "clean" URLs:</p>
<ul>
<li><strong>Old:</strong> <code>fezcode.com/#/blog/my-post</code></li>
<li><strong>New:</strong> <code>fezcode.com/blog/my-post</code></li>
</ul>
<p>But how do we make this work on a static host without a backend?</p>
<h2>The Solution Part 2: react-snap & SSG</h2>
<p>Enter <strong><a href="/vocab/ssg">Static Site Generation</a></strong> via <code>react-snap</code>. </p>
<p>Instead of shipping a nearly empty <code>index.html</code> and letting the browser build the page (<strong><a href="/vocab/csr">Client-Side Rendering</a></strong>), we now build the pages during the deployment phase. </p>
<ol>
<li><strong>The Crawl:</strong> During <code>npm run build</code>, <code>react-snap</code> fires up a headless browser (Puppeteer).</li>
<li><strong>The Snapshot:</strong> It visits every route defined in our sitemap and apps list.</li>
<li><strong>The Export:</strong> It captures the fully rendered HTML (including meta tags, titles, and unique descriptions) and saves it as a physical <code>index.html</code> file in a matching folder structure.</li>
</ol>
<p>In our latest build, this generated <strong>281 unique HTML files</strong>. Now, when you share a link, the crawler sees a real, static HTML file with the correct <strong><a href="/vocab/open-graph">Open Graph</a></strong> tags immediately.</p>
<h2>The Solution Part 3: Hydration</h2>
<p>Once the browser loads the static HTML, we don't want to lose the interactivity of React. I updated <code>src/index.js</code> to use <code>ReactDOM.hydrateRoot</code>. </p>
<p>This process, known as <strong><a href="/vocab/hydration">Hydration</a></strong>, allows React to "attach" to the existing HTML already on the screen rather than re-rendering everything from scratch. It preserves the fast initial load of a static site with the power of a modern web app.</p>
<h2>Global Content Cleanup</h2>
<p>Switching the router was only half the battle. Thousands of internal links within our <code>.piml</code> logs and <code>.txt</code> blog posts still pointed to the old <code>/#/</code> structure.</p>
<p>I executed a global recursive replacement across the <code>public/</code> directory:</p>
<pre><code class="language-powershell">Get-ChildItem -Path public -Include *.json, *.txt, *.piml, *.md -Recurse |
ForEach-Object { (Get-Content $_.FullName) -replace '/#/', '/' | Set-Content $_.FullName }
</code></pre>
<p>This ensured that the entire ecosystem—from the timeline to the project descriptions—is now synchronized with the new routing architecture.</p>
<h2>Conclusion</h2>
<p>Fezcodex is no longer just a Single Page Application; it is a high-performance, SEO-optimized static engine. Clean URLs, unique thumbnails, and faster perceived load times are now the standard.</p>
<p><a href="https://fezcode.com/blog/routing-revolution-ssg-and-seo">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Art of the Algorithm: Generative Visuals in Fezcodex]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/art-generation-in-fezcodex</link>
<guid isPermaLink="false">https://fezcode.com/blog/art-generation-in-fezcodex</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Sat, 20 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Art in the digital age isn't just about pixels and brushes; it's about rules, logic, and mathematics. In Fezcodex, I've integrated several "visual experiments" that turn code into aesthetics. From the subtle backgrounds of cards to full-blown design laboratories, let's explore how these algorithms work.</p>
<h2>The Heart: GenerativeArt</h2>
<p>You might have noticed unique geometric patterns appearing behind various elements in the site. These are powered by the <code>GenerativeArt</code> component.</p>
<h3>Seeded Randomness</h3>
<p>Imagine you have a robot that can draw. If you tell the robot "draw something random," it might draw a circle today and a square tomorrow. But what if you want the robot to draw the <strong>same</strong> "random" thing every time you say the word "Apple"?</p>
<p>That is what a <strong>Seed</strong> does. The algorithm takes a word (like a project name or a date), turns it into a number, and uses that number to make every "random" choice. Because the starting number is the same, the result is always the same. This is why "Project A" always has its own unique, permanent visual identity.</p>
<h3>How it generates symbols</h3>
<p>The component uses a "Bauhaus Grid" logic to create symbols. Here is the step-by-step:</p>
<ol>
<li><strong>The Grid:</strong> It divides a square into a 5x5 grid.</li>
<li><strong>The Coin Flip:</strong> For each square in the grid, it flips a digital coin to decide if it should draw something there.</li>
<li><strong>The Shape:</strong> If it decides to draw, it picks one of four shapes: a square, a circle, a quarter-circle, or a triangle.</li>
<li><strong>The Twist:</strong> It rotates the shape by 0, 90, 180, or 270 degrees.</li>
<li><strong>The Color:</strong> It picks colors from a palette generated based on the same seed.</li>
</ol>
<p>By combining these simple rules, the algorithm creates complex, balanced symbols that look like modern art but are just math in disguise.</p>
<h2>The Laboratory: BlendLab</h2>
<p>While <code>GenerativeArt</code> is about sharp geometry, <strong>BlendLab</strong> is about atmosphere and "vibe." It uses a coordinate-based system to create abstract color fields.</p>
<p>In BlendLab, you position different "entities" (points of color) on a digital canvas. The algorithm then applies heavy Gaussian blurs and noise filters. This blends the distinct points into a smooth, flowing gradient. When combined with high-impact typography, it creates a style often seen in modern "Brutalist" design.</p>
<h2>The Creative Suite</h2>
<p>Beyond these two, Fezcodex houses several other specialized art generators:</p>
<ul>
<li><strong>Topographic Maps:</strong> Uses "Perlin Noise" (a type of smooth, natural-looking randomness) to create height maps. By drawing lines at specific height levels, it creates the look of a physical map.</li>
<li><strong>Abstract Waves:</strong> Uses Trigonometry (Sine and Cosine waves). By layering multiple waves with slight offsets and adding a "noise" distortion, it generates 3D-looking landscapes reminiscent of retro album covers.</li>
<li><strong>Fractal Flora:</strong> Uses "Recursion"—a function that calls itself. To draw a tree, the code draws a trunk, then tells itself to "draw two smaller branches at the end," and repeats this until a full, organic-looking tree is formed.</li>
<li><strong>Spirograph:</strong> Uses the classic math of hypotrochoids and epitrochoids. It tracks the path of a point on a circle rolling inside or outside another circle.</li>
</ul>
<h2>Conclusion</h2>
<p>Code is often seen as cold and rigid, but when we introduce randomness and recursion, it becomes a brush. Fezcodex is a sandbox for these experiments, proving that the pursuit of code can indeed be an art form.</p>
<p><a href="https://fezcode.com/blog/art-generation-in-fezcodex">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Brutalist Fezcodex: The Big Cleanup]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/brutalist-refactor</link>
<guid isPermaLink="false">https://fezcode.com/blog/brutalist-refactor</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Today was a huge day for Fezcodex. We did a "Major Refactor."</p>
<h3>What did we change?</h3>
<ol>
<li><strong>Brutalist Style</strong>: We made the site look bold and strong, like a high-tech terminal. Big letters, sharp edges, and high contrast.</li>
<li><strong>Generative Art</strong>: We added "math art" that draws itself in the background. It's unique every time you look at it!</li>
<li><strong>Timeline & Games</strong>: We updated the Timeline and the Memory Game to fit this cool new look.</li>
<li><strong>The "Under the Hood" Stuff</strong>: We cleaned up the code (the "linter" stuff). We removed unused pieces and fixed tiny mistakes that make the computer happy.</li>
</ol>
<p>The garden is now cleaner, faster, and much more "Brutalist."</p>
<h2>Enjoy the new vibe!</h2>
<p><em>Log Entry: 2025-12-19</em></p>
<p><a href="https://fezcode.com/blog/brutalist-refactor">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Introducing New Reading Modes: Dossier and Terminal!]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/introducing-reading-experience</link>
<guid isPermaLink="false">https://fezcode.com/blog/introducing-reading-experience</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Excited to unveil two brand new ways to experience content on Fezcodex Blogposts: <strong>Dossier Mode</strong> and <strong>Terminal Mode!</strong>
These unique reading modes are designed to offer a fresh and engaging perspective, allowing you to tailor your browsing experience to your personal style.</p>
<h2>What's New?</h2>
<h3>1. Dossier Mode</h3>
<p>Step into the role of an investigator with <strong>Dossier Mode</strong>. This mode transforms the blogpost's interface into a sleek,
document-style layout, reminiscent of classified files and confidential reports. It's perfect for those who appreciate a clean,
minimalist aesthetic and want to immerse themselves in content without distractions, feeling like they're poring over important case files.</p>
<h3>2. Terminal Mode</h3>
<p>For the tech enthusiasts and command-line aficionados, we present <strong>Terminal Mode</strong>. This mode re-skins blogposts with a retro,
monospaced font, glowing green text, and a classic command-line interface feel. It's an homage to the early days of computing,
offering a nostalgic and functional environment that's ideal for developers, hackers, or anyone who enjoys a vintage digital vibe while consuming content.</p>
<blockquote>
<p>Inspired by Fallout: New Vegas colors</p>
</blockquote>
<h2>Why build this?</h2>
<p>The goal is to continually innovate and provide diverse ways for our users to interact with our content.
I believe that offering distinct visual experiences like Dossier and Terminal modes enhances user engagement
and allows for a more personalized journey through Fezcodex.</p>
<p>Head over to the <a href="/settings">Settings page</a> (accessible from the Sidebar). Scroll down to the new <strong>Reading Experience</strong> section and set you mode...</p>
<h1>Oh, One More Thing. <em><strong>Sidebar Colors</strong></em></h1>
<p>Also sidebar now supports multiple background colors. Some of your favorite even.</p>
<ul>
<li><span style="background-color: rgba(250, 128, 114, 0.5)"> Salmon Light </span></li>
<li><span style="background-color: rgba(250, 128, 114, 0.75)"> Salmon Medium </span></li>
<li><span style="background-color: rgba(100, 149, 237, 0.5)"> Blue </span></li>
<li><span style="background-color: rgba(60, 179, 113, 0.5)"> Green </span></li>
<li><span style="background-color: rgba(147, 112, 219, 0.5)"> Purple </span></li>
<li><span style="background-color: rgba(0, 255, 255, 0.5)"> Cyan </span></li>
</ul>
<p>Head over to the <a href="/settings">Settings page</a>, again. Scroll down to the new <strong>Interface & Layout</strong> then under <strong>Sidebar Color</strong> section set your sidebar color.</p>
<p>Hope you enjoy exploring these new immersive reading modes. Happy reading!</p>
<p><a href="https://fezcode.com/blog/introducing-reading-experience">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Typeface vs. Font: The Music Analogy]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/typeface-vs-font</link>
<guid isPermaLink="false">https://fezcode.com/blog/typeface-vs-font</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>The easiest way to understand the difference is to think about music:</p>
<ul>
<li><strong>The Typeface</strong> is the <strong>song</strong> itself (the melody, the lyrics, the creative idea).</li>
<li><strong>The Font</strong> is the <strong>MP3 file</strong> (the actual digital file you use to play the music).</li>
</ul>
<p>In design terms:</p>
<ul>
<li><strong>Typeface</strong>: The specific design or look of the letters (what you see).</li>
<li><strong>Font</strong>: The computer file or mechanism that contains the letters (what you use).</li>
</ul>
<h2>In Practice</h2>
<p>You choose a <strong>Typeface</strong>, but you install a <strong>Font</strong>.</p>
<h2>Examples</h2>
<h4>1. Helvetica</h4>
<ul>
<li>Typeface: "Helvetica" (The entire family of letters).</li>
<li>Font: <code>Helvetica-Bold.otf</code> (The specific file for the bold version).</li>
</ul>
<h4>2. Times New Roman</h4>
<ul>
<li>Typeface: "Times New Roman" (The creative design).</li>
<li>Font: <code>Times New Roman, Italic, 12 point</code> (The specific variation you are using on the page).</li>
</ul>
<h2>Summary</h2>
<p>If you are talking to a designer about the look, you are talking about a <strong>Typeface</strong>.
If you are talking to a developer about the file or the bold setting, you are talking about a <strong>Font</strong>.</p>
<p><a href="https://fezcode.com/blog/typeface-vs-font">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Why Your Brain Hates Lyrics While You Work: The Irrelevant Speech Effect]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/the-irrelevant-speech-effect</link>
<guid isPermaLink="false">https://fezcode.com/blog/the-irrelevant-speech-effect</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Have you ever tried to read a book while someone next to you is having a loud conversation on the phone?
You probably found yourself reading the same sentence three times without understanding a word.</p>
<p>This isn't because you aren't focused; it is because of a psychological glitch called the <strong>Irrelevant Speech Effect (ISE)</strong>.</p>
<p>Here is the simple breakdown of why this happens and why your favorite playlist might be killing your productivity.</p>
<h2>What is the "Irrelevant Speech Effect"?</h2>
<p>Imagine your brain’s working memory is like a <strong>single-lane bridge</strong>. This bridge is responsible for processing language—whether that's reading an email, writing code, or studying for an exam.</p>
<p>When you are working, you are sending "cars" (words and thoughts) over this bridge.</p>
<ul>
<li>Silence: The cars move smoothy.</li>
<li>Instrumental Music: A little scenery on the side of the road, but the traffic flows.</li>
<li>Speech (or Lyrics): This is like a massive truck trying to force its way onto that same single-lane bridge from the opposite direction.</li>
</ul>
<p>Even if you <em>try</em> to ignore the speech, you can't. Your brain is hardwired to prioritize human voices.
It involuntarily tries to process the words it hears, causing a traffic jam on the bridge. This crash is the Irrelevant Speech Effect.
Why You Shouldn't Listen to Lyrical Music While Working</p>
<p>You might think, <strong>"I'm not listening to the lyrics, I'm just vibing."</strong> Unfortunately, your subconscious disagrees.</p>
<p>If your task involves words (reading, writing, coding, planning), your brain uses a system called the <strong>Phonological Loop.</strong>
This is the inner voice you hear when you read silently.</p>
<p>When you play music with lyrics:</p>
<ul>
<li>Conflict: Your inner voice (reading/thinking) starts fighting with the singer's voice.</li>
<li>Processing Power: Your brain wastes energy trying to filter out the singer's words to focus on your own thoughts.</li>
<li>Result: Your IQ temporarily drops, you make more mistakes, and you get tired faster.</li>
</ul>
<h3>Real-Life Examples</h3>
<ul>
<li>The Coffee Shop Dilemma: You can work fine in a coffee shop with the hum of a machine or clinking cups (white noise). But the moment the couple at the next table starts arguing about their relationship, your focus shatters.-</li>
<li>The Open Office: You are trying to write an important email, but a colleague two desks away is explaining a recipe. Suddenly, you find yourself typing "pasta" into your professional report.-</li>
<li>TV in the Background: You think having the news on helps you relax while studying, but you realize you’ve been staring at the same page for 20 minutes because your brain is tracking the reporter's voice.</li>
</ul>
<h3>The Solution?</h3>
<p>If you are doing manual labor (like washing <strong>dishes</strong>), lyrical music is great! <strong>It keeps you energized.</strong></p>
<p>But for deep mental work:</p>
<ul>
<li>Stick to Lo-Fi beats, Classical, or Video Game Soundtracks.</li>
<li>These genres have no words, so they occupy the "emotional" part of your brain without crashing into the "language" bridge.</li>
</ul>
<p><a href="https://fezcode.com/blog/the-irrelevant-speech-effect">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[React Hooks Showdown: useMemo vs useCallback vs useState vs useEffect]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/react-hooks-comparison</link>
<guid isPermaLink="false">https://fezcode.com/blog/react-hooks-comparison</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Mon, 15 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h2>1. useState: The Memory</h2>
<p><a href="https://fezcode.com/blog/react-hooks-comparison">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[React Magic: Rendering Components from Markdown Links]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/react-magic-markdown-components</link>
<guid isPermaLink="false">https://fezcode.com/blog/react-magic-markdown-components</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Fri, 12 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Static text is boring. In a modern React application, your content should be alive.</p>
<p>Today I want to share a fun pattern I implemented in <strong>Fezcodex</strong>: triggering dynamic UI interactions directly from standard Markdown links. Specifically, clicking a link in a blog post to open a side panel with a live React component, rather than navigating to a new page.</p>
<h2>The Idea</h2>
<p>I wanted to explain technical terms like <strong><a href="/vocab/prop-drilling">Prop Drilling</a></strong> without forcing the reader to leave the article. A tooltip is too small; a new tab is too distracting. The solution? My global <strong>Side Panel</strong>.</p>
<p>But how do you tell a static Markdown file to "render a React component in the side panel"?</p>
<h2>The Solution</h2>
<p>The secret sauce lies in <code>react-markdown</code>'s ability to customize how HTML elements are rendered. We can intercept every <code><a></code> tag and check if it's a "special" link.</p>
<h3>1. The Interceptor (<code>MarkdownLink</code>)</h3>
<p>I created a custom component that replaces standard HTML anchors. It checks the <code>href</code> for a specific pattern (in my case, <code>/vocab/</code>).</p>
<pre><code class="language-javascript">const MarkdownLink = ({ href, children }) => {
const { openSidePanel } = useSidePanel();
// Check if this is a "vocabulary" link
const isVocab = href && href.includes('/vocab/');
if (isVocab) {
// 1. Extract the term ID (e.g., "prop-drilling")
const term = href.split('/vocab/')[1];
// 2. Look up the definition/component
const definition = vocabulary[term];
return (
<a
href={href}
onClick={(e) => {
e.preventDefault(); // Stop navigation!
if (definition) {
// 3. Trigger the global UI
openSidePanel(definition.title, definition.content);
}
}}
className="text-pink-400 dashed-underline cursor-help"
>
{children}
</a>
);
}
// Fallback for normal links
return <a href={href}>{children}</a>;
};
</code></pre>
<h3>2. The Data (<code>vocabulary.js</code>)</h3>
<p>I store the actual content in a simple lookup object. The beauty is that <code>content</code> can be <em>anything</em>--text, images, or fully interactive React components.</p>
<pre><code class="language-javascript">export const vocabulary = {
'prop-drilling': {
title: 'Prop Drilling',
content: <PropDrillingDiagram /> // A real component!
},
// ...
};
</code></pre>
<h3>3. Handling "Deep Links"</h3>
<p>What if someone actually copies the URL <code>https://fezcodex.com/vocab/prop-drilling</code> and sends it to a friend? The <code>onClick</code> handler won't fire because they aren't clicking a link—they are loading the app.</p>
<p>To handle this, I added a "phantom" route in my Router:</p>
<pre><code class="language-javascript">// VocabRouteHandler.js
const VocabRouteHandler = () => {
const { term } = useParams();
const navigate = useNavigate();
const { openSidePanel } = useSidePanel();
useEffect(() => {
// 1. Open the panel immediately
if (vocabulary[term]) {
openSidePanel(vocabulary[term].title, vocabulary[term].content);
}
// 2. Redirect to home (so the background isn't blank)
navigate('/', { replace: true });
}, [term]);
return null;
};
</code></pre>
<h2>Why this rocks</h2>
<p>This pattern effectively turns your static Markdown content into a control surface for your application. You can write:</p>
<blockquote>
<p>"Check out this <code>[interactive demo](/demos/sorting-algo)</code>..."</p>
</blockquote>
<p>And have it launch a full-screen visualization, a game, or a configuration wizard, all without leaving the flow of your writing. It bridges the gap between "content" and "app".</p>
<p><a href="https://fezcode.com/blog/react-magic-markdown-components">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Implementing a Resizable Global Sliding Side Panel in React]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/implementing-a-sliding-side-panel</link>
<guid isPermaLink="false">https://fezcode.com/blog/implementing-a-sliding-side-panel</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Thu, 11 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Sometimes, a modal is just too intrusive. You want to show detailed context—like a complex rating system or metadata—without forcing the user to lose their place on the page or blocking the entire UI with a backdrop that demands immediate attention. Enter the <strong>Sliding Side Panel</strong>.</p>
<p>In this post, I'll walk through how I implemented a global side panel system for <strong>Fezcodex</strong>, allowing any component in the app to trigger a content-rich overlay that slides in smoothly from the right. Even better? I made it <strong>resizable</strong>, so users can drag to expand the view if they need more space.</p>
<h2>The Goal</h2>
<p>The immediate need was simple: I wanted to explain my G4-inspired 5-star rating system on the Logs page. A simple tooltip wasn't enough, and a full modal felt heavy-handed. I wanted a panel that felt like an extension of the UI, sliding in to offer "more details" on demand.</p>
<h2>The Architecture</h2>
<p>To make this truly reusable, I avoided prop drilling by using the <strong>Context API</strong>.</p>
<h3>Why Context? Avoiding Prop Drilling</h3>
<p>Without a global context, implementing a feature like this would require <strong><a href="/vocab/prop-drilling">prop drilling</a></strong>. This is a common pattern (or <strong><a href="/vocab/anti-pattern">anti-pattern</a></strong>) in React where you pass data or functions down through multiple layers of components just to get them to where they are needed.</p>
<p>Imagine we managed the side panel state in <code>App.js</code>. We would have to pass the <code>openSidePanel</code> function like this:</p>
<p><code>App</code> → <code>Layout</code> → <code>MainContent</code> → <code>LogsPage</code> → <code>LogCard</code> → <code>InfoButton</code></p>
<p>Every intermediate component would need to accept and pass along a prop it doesn't even use. This makes refactoring a nightmare and clutters your component signatures. By using the <strong>Context API</strong>, we can bypass the middle layers entirely. Any component, no matter how deep in the tree, can simply reach out and grab the <code>openSidePanel</code> function directly.</p>
<h3>1. The Context (<code>SidePanelContext</code>)</h3>
<p>We need a way to tell the app: "Open the panel with <em>this</em> title, <em>this</em> content, and start at <em>this</em> width."</p>
<pre><code class="language-javascript">// src/context/SidePanelContext.js
import React, { createContext, useContext, useState } from 'react';
const SidePanelContext = createContext();
export const useSidePanel = () => useContext(SidePanelContext);
export const SidePanelProvider = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const [panelContent, setPanelContent] = useState(null);
const [panelTitle, setPanelTitle] = useState('');
const [panelWidth, setPanelWidth] = useState(450); // Default width
// openSidePanel now accepts an optional initial width
const openSidePanel = (title, content, width = 450) => {
setPanelTitle(title);
setPanelContent(content);
setPanelWidth(width);
setIsOpen(true);
};
const closeSidePanel = () => setIsOpen(false);
return (
<SidePanelContext.Provider
value={{
isOpen,
panelTitle,
panelContent,
panelWidth,
setPanelWidth,
openSidePanel,
closeSidePanel
}}
>
{children}
</SidePanelContext.Provider>
);
};
</code></pre>
<p>This allows any component to call <code>openSidePanel('My Title', <MyComponent />, 600)</code> to trigger the UI with a custom starting width.</p>
<h3>2. The Component (<code>SidePanel</code>)</h3>
<p>The visual component uses <strong>Framer Motion</strong> for silky smooth entrance and exit animations, and vanilla JS event listeners for the resize logic.</p>
<pre><code class="language-javascript">// src/components/SidePanel.js
import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect } from 'react';
import { useSidePanel } from '../context/SidePanelContext';
const SidePanel = () => {
const { isOpen, closeSidePanel, panelTitle, panelContent, panelWidth, setPanelWidth } = useSidePanel();
const [isResizing, setIsResizing] = useState(false);
// Resize Logic
useEffect(() => {
const handleMouseMove = (e) => {
if (!isResizing) return;
const newWidth = window.innerWidth - e.clientX;
// Constrain width: min 300px, max 90% of screen
if (newWidth > 300 && newWidth < window.innerWidth * 0.9) {
setPanelWidth(newWidth);
}
};
const handleMouseUp = () => setIsResizing(false);
if (isResizing) {
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
document.body.style.cursor = 'ew-resize';
document.body.style.userSelect = 'none'; // Prevent text selection while dragging
}
return () => {
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
document.body.style.cursor = 'default';
document.body.style.userSelect = 'auto';
};
}, [isResizing, setPanelWidth]);
return (
<AnimatePresence>
{isOpen && (
<>
<motion.div onClick={closeSidePanel} className="fixed inset-0 bg-black/50 z-[60]" />
<motion.div
initial={{ x: '100%' }}
animate={{ x: 0 }}
exit={{ x: '100%' }}
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
style={{ width: panelWidth }} // Dynamic width
className="fixed top-0 right-0 h-full bg-gray-900 border-l border-gray-700 z-[70] flex flex-col"
>
{/* Resize Handle */}
<div
onMouseDown={(e) => { setIsResizing(true); e.preventDefault(); }}
className="absolute left-0 top-0 bottom-0 w-1.5 cursor-ew-resize hover:bg-primary-500/50 transition-colors z-50"
/>
{/* Header & Content */}
</motion.div>
</>
)}
</AnimatePresence>
);
};
</code></pre>
<h3>3. Integration</h3>
<p>I wrapped the entire application in the <code>SidePanelProvider</code> in <code>App.js</code> and placed the <code><SidePanel /></code> component in <code>Layout.js</code>. This ensures the panel is always available and renders on top of everything else.</p>
<h2>Inspiration</h2>
<p>The first use case for this panel was to detail the <strong>Rating System</strong> for my logs. I wanted to pay homage to the classic <strong>X-Play (G4TV)</strong> scale, emphasizing that a <strong>3 out of 5</strong> is a solid, good score—not a failure.</p>
<p>The side panel proved perfect for this: users can check the rating criteria without leaving the logs list, keeping their browsing flow uninterrupted.</p>
<h2>Conclusion</h2>
<p>Global UI elements controlled via Context are a powerful pattern in React. By adding a simple resize handle and managing width in the global state, we've transformed a static overlay into a flexible, user-friendly tool that adapts to the user's needs.</p>
<p><a href="https://fezcode.com/blog/implementing-a-sliding-side-panel">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Building a Digital Rotary Phone]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/building-a-digital-rotary-phone</link>
<guid isPermaLink="false">https://fezcode.com/blog/building-a-digital-rotary-phone</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Tue, 02 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>In a world of touchscreens and haptic feedback, there's something deeply satisfying about the mechanical click-whirrr of a rotary phone.
I recently built a digital version of this retro interface for Fezcodex, and I want to take you through the engineering journey—from the
trigonometry of the dial to the state management of the call logic.</p>
<h2>The Challenge</h2>
<p>Building a rotary phone for the web isn't just about displaying an image. It's about capturing the <em>feel</em> of the interaction. You need to:</p>
<ol>
<li>Draw a dial with holes.</li>
<li>Detect user input (mouse or touch).</li>
<li>Calculate the rotation based on the pointer's position.</li>
<li>"Drag" the dial realistically.</li>
<li>Snap back when released.</li>
<li>Register the dialed number only if the user drags far enough.</li>
</ol>
<h2>Anatomy of the Dial</h2>
<p>I broke the <code>RotaryDial</code> component into a few key layers, stacked using CSS absolute positioning:</p>
<ol>
<li><strong>The Backplate</strong>: This is static. It sits at the bottom and holds the numbers (1, 2, 3... 0) in their correct positions.</li>
<li><strong>The Rotating Disk</strong>: This sits on top of the backplate. It rotates based on user interaction. It contains the "holes".</li>
<li><strong>The Finger Stop</strong>: A static hook at the bottom right (approx 4 o'clock position) that physically stops the dial on a real phone.</li>
</ol>
<h3>The Trigonometry of Angles</h3>
<p>The core of this component is converting a mouse position (x, y) into an angle (theta).</p>
<pre><code class="language-javascript">const getAngle = (event, center) => {
const clientX = event.touches ? event.touches[0].clientX : event.clientX;
const clientY = event.touches ? event.touches[0].clientY : event.clientY;
const dx = clientX - center.x;
const dy = clientY - center.y;
// atan2 returns angle in radians, convert to degrees
let theta = Math.atan2(dy, dx) * (180 / Math.PI);
return theta;
};
</code></pre>
<p><code>Math.atan2(dy, dx)</code> is perfect here because it handles all quadrants correctly, returning values from -PI to +PI (-180 to +180 degrees).</p>
<h3>Why <code>Math.atan2</code>?</h3>
<p>You might remember SOH CAH TOA from school. To find an angle given x and y, we typically use the tangent function: <code>tan(θ) = y / x</code>, so <code>θ = atan(y / x)</code>.</p>
<p>However, <code>Math.atan()</code> has a fatal flaw for UI interaction: it can't distinguish between quadrants.</p>
<ul>
<li>Quadrant 1: x=1, y=1 -> <code>atan(1/1)</code> = 45°</li>
<li>Quadrant 3: x=-1, y=-1 -> <code>atan(-1/-1)</code> = <code>atan(1)</code> = 45°</li>
</ul>
<p>If we used <code>atan</code>, dragging in the bottom-left would behave exactly like dragging in the top-right!</p>
<p><code>Math.atan2(y, x)</code> solves this by taking both coordinates separately. It checks the signs of x and y to place the angle in the correct full-circle context (-π to +π radians).</p>
<p>We then convert this radian value to degrees:
<code>Degrees = Radians * (180 / π)</code></p>
<p>This gives us a continuous value we can use to map the mouse position directly to the dial's rotation.</p>
<h2>The Drag Logic</h2>
<p>When a user clicks a specific number's hole, we don't just start rotating from 0. We need to know <em>which</em> hole they grabbed.</p>
<p>Each digit has a "Resting Angle". If the Finger Stop is at 60 degrees, and the holes are spaced 30 degrees apart:</p>
<ul>
<li>Digit 1 is at <code>60 - 30 = 30</code> degrees.</li>
<li>Digit 2 is at <code>60 - 60 = 0</code> degrees.</li>
<li>...and so on.</li>
</ul>
<p>When the user starts dragging, we track the mouse's current angle relative to the center of the dial. The rotation of the dial is then calculated as:</p>
<p><code>Rotation = CurrentMouseAngle - InitialHoleAngle</code></p>
<h3>Handling the "Wrap Around"</h3>
<p>One of the trickiest parts was handling the boundary where angles jump from 180 to -180. For numbers like 9 and 0, the rotation requires dragging past this boundary.</p>
<p>If you just subtract the angles, you might get a jump like <code>179 -> -179</code>, which looks like a massive reverse rotation. I solved this with a normalization function:</p>
<pre><code class="language-javascript">const normalizeDiff = (diff) => {
while (diff <= -180) diff += 360;
while (diff > 180) diff -= 360;
return diff;
};
</code></pre>
<p>However, simply normalizing isn't enough for the long throws (like dragging '0' all the way around). A normalized angle might look like <code>-60</code> degrees, but we actually mean <code>300</code> degrees of positive rotation.</p>
<p>I added logic to detect this "underflow":</p>
<pre><code class="language-javascript">// If rotation is negative but adding 360 keeps it within valid range
if (newRotation < 0 && (newRotation + 360) <= maxRot + 30) {
newRotation += 360;
}
</code></pre>
<p>This ensures that dragging '0' feels continuous, even as it passes the 6 o'clock mark.</p>
<h2>State Management vs. Animation</h2>
<p>Initially, I used standard React state (<code>useState</code>) for the rotation. This worked, but <code>setState</code> is asynchronous and can feel slightly laggy for high-frequency drag events (60fps).</p>
<p>I switched to <strong>Framer Motion's <code>useMotionValue</code></strong>. This allows us to update the rotation value directly without triggering a full React re-render on every pixel of movement. It's buttery smooth.</p>
<pre><code class="language-javascript">const rotation = useMotionValue(0);
// ...
rotation.set(newRotation);
</code></pre>
<p>When the user releases the dial (<code>handleEnd</code>), we need it to spring back to zero. Framer Motion makes this trivial:</p>
<pre><code class="language-javascript">animate(rotation, 0, {
type: "spring",
stiffness: 200,
damping: 20
});
</code></pre>
<h2>The "Call" Logic</h2>
<p>The drag logic only handles the visual rotation. To actually dial a number, we check the final rotation when the user releases the mouse.</p>
<p>If <code>abs(CurrentRotation - MaxRotation) < Threshold</code>, we count it as a successful dial.</p>
<p>I connected this to a higher-level <code>RotaryPhonePage</code> component that maintains the string of dialed numbers.</p>
<h3>Easter Eggs</h3>
<p>Of course, no app is complete without secrets. I hooked up a <code>handleCall</code> function that checks specific number patterns:</p>
<ul>
<li><strong>911</strong>: Triggers a red "Connected" state and unlocks "The Emergency" achievement.</li>
<li><strong>0</strong>: Connects to the Operator.</li>
<li><strong>Others</strong>: Just simulates a call.</li>
</ul>
<h2>Visuals</h2>
<p>The dial uses Tailwind CSS for styling. The numbers and holes are positioned using <code>transform: rotate(...) translate(...)</code>.</p>
<ul>
<li><code>rotate(angle)</code> points the element in the right direction.</li>
<li><code>translate(radius)</code> pushes it out from the center.</li>
<li><code>rotate(-angle)</code> (on the inner text) keeps the numbers upright!</li>
</ul>
<p>The result is a responsive, interactive, and nostalgic component that was a joy to build. Give it a spin in the <strong>Apps</strong> section!</p>
<p><a href="https://fezcode.com/blog/building-a-digital-rotary-phone">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Nocturnote: A Sleek and Modern Text Editor]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/nocturnote</link>
<guid isPermaLink="false">https://fezcode.com/blog/nocturnote</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Mon, 01 Dec 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<h2>Nocturnote: The Text Editor I Always Wanted</h2>
<p>Have you ever felt like your text editor is either doing too much or too little? That's exactly how I felt before I started building <strong>Nocturnote</strong>.</p>
<p><img src="/images/projects/nocturnote.png" alt="Nocturnote Notepad Mode"></p>
<blockquote>
<p>Notepad Mode in Nocturnote</p>
</blockquote>
<p><strong>Nocturnote</strong> is my take on a modern, distraction-free writing environment. It's a sleek, cross-platform desktop application designed for those who want to just <em>write</em>, but with the comfort of modern tools.</p>
<h2>Why Nocturnote?</h2>
<p>I wanted something that looked good, felt fast, and offered just the right amount of customization without being overwhelming.</p>
<h3>Key Features</h3>
<ul>
<li><strong>Distraction-Free Interface</strong>: Clean lines, subtle colors, and a focus on your text.</li>
<li><strong>Rain Mode</strong>: This is one of my favorites. Toggle it on for a soothing visual effect that adds a cozy atmosphere to your writing sessions.</li>
<li><strong>Notepad Mode</strong>: Sometimes you just want that classic, stripped-back aesthetic. Nocturnote has you covered.</li>
<li><strong>Full Customization</strong>: Change fonts, sizes, line heights, and more. Make it yours.</li>
</ul>
<h2>Under the Hood</h2>
<p>For the tech-savvy, Nocturnote is built using a robust modern stack:</p>
<ul>
<li><strong>Electron</strong>: Ensuring it runs smoothly on Windows, macOS, and Linux.</li>
<li><strong>Svelte 5</strong>: For a blazing fast and reactive user interface.</li>
<li><strong>TypeScript</strong>: Because type safety is non-negotiable.</li>
<li><strong>Tailwind CSS</strong>: For rapid and beautiful styling.</li>
<li><strong>Electron-Vite</strong>: For a lightning-fast development experience.</li>
</ul>
<h2>Get It</h2>
<p>Nocturnote is open source! You can check out the code, contribute, or download it from the repository.</p>
<p><a href="https://github.com/fezcode/nocturnote">Check out Nocturnote on GitHub</a></p>
<p>Whether you're coding, journaling, or taking quick notes, I hope Nocturnote provides the calm, productive space you need.</p>
<p><a href="https://fezcode.com/blog/nocturnote">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Art of Recursive Botany: How Fractal Flora Works]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/how-fractal-flora-works</link>
<guid isPermaLink="false">https://fezcode.com/blog/how-fractal-flora-works</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate>
<content:encoded><![CDATA[<p>Have you ever wondered how nature creates such intricate and beautiful patterns,
from the branching of trees to the delicate veins of a leaf? Much of this complexity can be explained by surprisingly simple rules,
often involving <strong>fractals</strong> and <strong>recursion</strong>.
Our new "Fractal Flora" app lets you explore these principles by growing your own digital trees with a few sliders.</p>
<blockquote>
<p><a href="/apps::flora">Try apps::flora here</a></p>
</blockquote>
<p>This post will peel back the layers and explain the core mechanics behind the app.</p>
<p><img src="/images/projects/fractal-flora.png" alt="/images/projects/fractal-flora.png"></p>
<h2>What is a Fractal Tree?</h2>
<p>At its heart, a fractal tree is a structure where a basic branching pattern repeats itself at smaller scales. Each branch can be thought of as a miniature version of the entire tree. This self-similarity is a hallmark of fractals.</p>
<p>In programming, this concept is perfectly suited for <strong>recursion</strong>, where a function calls itself to solve smaller instances of the same problem.</p>
<h2>The Recursive Algorithm: <code>drawBranch</code></h2>
<p>The entire tree is generated by a single, powerful recursive function, let's call it <code>branch()</code>. It takes a starting point, a length, an angle, and its current depth in the tree.</p>
<p>Here's a simplified look at its logic:</p>
<ol>
<li><strong>Draw the Current Branch:</strong> It draws a line segment from its starting point, at its given length and angle.</li>
<li><strong>Base Case (Stop Condition):</strong> If the <code>depth</code> (how many times it has branched) reaches zero, it stops. This prevents infinite recursion.</li>
<li><strong>Branch Out:</strong> Otherwise, it calculates the endpoint of the current branch. From this endpoint, it calls itself <em>twice</em> (or more), creating two new "sub-branches." Each sub-branch is drawn with a shorter length, a new angle (offset from the parent branch), and a reduced depth.</li>
</ol>
<pre><code class="language-javascript">const branch = (x, y, len, ang, d) => {
// 1. Calculate end point of current branch
const endX = x + len * Math.cos((ang * Math.PI) / 180);
const endY = y + len * Math.sin((ang * Math.PI) / 180);
// 2. Draw the branch (context.drawLine(x,y,endX,endY))
// 3. If not at max depth, recurse
if (d > 0) {
const nextLen = len * lengthMultiplier; // e.g., 0.7
// Right branch
branch(endX, endY, nextLen, ang + branchAngle, d - 1);
// Left branch
branch(endX, endY, nextLen, ang - branchAngle, d - 1);
}
};
// Initial call (e.g., from bottom center of canvas)
// branch(canvas.width / 2, canvas.height, initialLength, -90, maxDepth);
</code></pre>
<p><em>(Note: The actual implementation in <code>FractalFloraPage.js</code> is slightly more complex, handling canvas transformations, line widths, and randomized elements.)</em></p>
<h2>The "DNA" of Your Digital Tree</h2>
<p>The beauty of Fractal Flora lies in how these simple parameters (the tree's "DNA") dramatically change its appearance:</p>
<ul>
<li><strong>Recursion Depth (<code>depth</code>):</strong> This controls how many times the <code>branch()</code> function calls itself. A higher depth creates a denser, more complex tree, but also requires more computation.</li>
<li><strong>Branch Angle (<code>angle</code>):</strong> This is the angle at which new branches diverge from the parent branch. Small angles create tall, narrow trees, while larger angles create wider, more sprawling structures.</li>
<li><strong>Length Multiplier (<code>lengthMultiplier</code>):</strong> This determines how much shorter each successive branch becomes. A value of <code>0.7</code> means a new branch is 70% the length of its parent.</li>
<li><strong>Trunk Base Size (<code>lengthBase</code>):</strong> The initial length of the very first (main) trunk segment.</li>
<li><strong>Wind / Asymmetry (<code>asymmetry</code>):</strong> This parameter adds a bias to the branching angle, making one side of the tree grow more dominantly, simulating the effect of wind or environmental factors.</li>
<li><strong>Organic Randomness (<code>randomness</code>):</strong> This introduces slight, random variations to the length and angle of each branch, breaking the perfect symmetry of mathematical fractals and making the tree appear more organic and natural.</li>
</ul>
<h3>Seasons and Color Palettes</h3>
<p>The app also cycles through different "seasons." These aren't complex simulations, but rather pre-defined color palettes for the trunk, branches, and leaves, instantly changing the mood and appearance of your flora.</p>
<h2>From Math to Art</h2>
<p>What's fascinating is how a few lines of code, driven by recursive mathematical principles, can generate forms that closely mimic those found in nature. Fractals are not just abstract mathematical concepts; they are the language of growth, efficiency, and beauty in the natural world.</p>
<p>Now that you understand the "how," dive back into the Fractal Flora app and become a digital botanist, experimenting with its DNA to create your own unique, algorithmic arboretum!</p>
<p><a href="https://fezcode.com/blog/how-fractal-flora-works">Read more...</a></p>]]></content:encoded>
</item>
<item>
<title><![CDATA[Unlocking Your Journey: Introducing the Fezcodex Achievement System!]]></title>
<description><![CDATA[[object Object]]]></description>
<link>https://fezcode.com/blog/the-fezcodex-achievement-system</link>
<guid isPermaLink="false">https://fezcode.com/blog/the-fezcodex-achievement-system</guid>
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
<pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate>