-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
997 lines (943 loc) · 68.3 KB
/
Copy pathindex.html
File metadata and controls
997 lines (943 loc) · 68.3 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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MeshRoute v2.0 — Optimal Mesh Network Routing</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<!-- NAV -->
<nav id="navbar">
<div class="nav-inner">
<a href="#hero" class="logo">MESH<span>ROUTE</span></a>
<button class="nav-toggle" id="nav-toggle" aria-label="Menu">☰</button>
<ul id="nav-menu">
<li><a href="#problem">Problem</a></li>
<li><a href="#approaches">Approaches</a></li>
<li><a href="#math">Math</a></li>
<li><a href="#winner">Winner</a></li>
<li><a href="#formation">Formation</a></li>
<li><a href="#scenarios">Scenarios</a></li>
<li><a href="#resilience">Resilience</a></li>
<li><a href="#sim-results">Results</a></li>
<li><a href="#glossary">Glossary</a></li>
<li class="nav-sep"></li>
<li><a href="simulator.html" style="color:var(--cyan)">Live Simulator</a></li>
<li><a href="how-it-works.html">How It Works</a></li>
<li><a href="docs/esp-test-results.html" style="color:var(--green)">ESP32 Test</a></li>
<li><a href="analysis.html">Analysis</a></li>
<li><a href="summary.html">Summary</a></li>
<li class="nav-sep"></li>
<li><a href="de/index.html" title="Deutsch" style="font-size:1.2rem;line-height:1;padding:0.2rem 0.5rem">🇩🇪</a></li>
</ul>
</div>
</nav>
<!-- HERO -->
<section id="hero">
<canvas id="hero-canvas"></canvas>
<div class="hero-content">
<div class="hero-tag">Research & Algorithm Design</div>
<h1 class="hero-title">Mesh<span class="accent">Route</span> <span style="font-size:0.35em;color:var(--text-muted);font-family:var(--font-mono);vertical-align:super">v2.0</span></h1>
<p class="hero-sub">Finding the optimal communication path between LoRa mesh devices — before a single byte of payload is transmitted.</p>
<div class="hero-badges">
<span class="badge active">LoRa / Meshtastic</span>
<span class="badge">Multi-Path</span>
<span class="badge">Load Balanced</span>
<span class="badge">Geo-Clustered</span>
</div>
<p style="margin-top:1.5rem;font-family:var(--font-mono);font-size:0.8rem;color:var(--text-muted);opacity:0;animation:fadeUp 0.8s 1.1s forwards">by Clemens Simon</p>
</div>
</section>
<!-- TL;DR -->
<section id="tldr">
<div class="section-tag reveal">00 — TL;DR</div>
<div class="tldr-card reveal">
<p class="tldr-text">Half-duplex radio physics collapse managed flooding to <strong>0–60% delivery</strong> in ALL scenarios — not just Bay Area. <strong>System V6</strong> combines geo-clustering, multi-path routing, and adaptive QoS into one self-healing protocol. For networks up to ~200 nodes: <strong>100% delivery with 92–99.9% less bandwidth</strong> (vs flooding's 27–87%). At 500+ nodes: <strong>dramatically higher delivery</strong> (76% vs 3% at 500 nodes). The hop limit — today's biggest scaling bottleneck — becomes irrelevant: each hop costs <strong>~1 transmission</strong> instead of <em>n</em>.</p>
<div class="tldr-stats">
<div class="tldr-stat"><span class="tldr-num">100%</span><span class="tldr-label">Del. ≤200</span></div>
<div class="tldr-stat"><span class="tldr-num">99.9%</span><span class="tldr-label">BW Saved</span></div>
<div class="tldr-stat"><span class="tldr-num">~1</span><span class="tldr-label">TX/Hop</span></div>
<div class="tldr-stat"><span class="tldr-num">∞</span><span class="tldr-label">Hop Limit</span></div>
<div class="tldr-stat"><span class="tldr-num">26</span><span class="tldr-label">Scenarios</span></div>
</div>
</div>
</section>
<!-- PROBLEM -->
<section id="problem">
<div class="section-tag reveal">01 — The Problem</div>
<h2 class="section-title reveal">Why Current Mesh Routing Fails</h2>
<p class="section-desc reveal">Meshtastic uses flooding: every node rebroadcasts every packet, hoping it reaches the destination. This design was fine when mesh networks had 10–30 nodes. But as communities like Bay Area Mesh, NYC Mesh, and European Freifunk grow to hundreds or thousands of devices, the approach breaks down in five fundamental ways.</p>
<div class="problem-grid">
<div class="problem-card reveal">
<div class="icon">📡</div>
<h3>Blind Flooding</h3>
<p>Every message is rebroadcast by every node that receives it. A single message to one recipient generates <strong>n transmissions</strong> across the entire network.</p>
</div>
<div class="problem-card reveal">
<div class="icon">⏳</div>
<h3>LoRa Constraints</h3>
<p>1–50 kbps bandwidth. 1% duty cycle (EU law). Half-duplex radio. Each packet takes 50ms–2s airtime. Budget: ~36–720 packets/hour/node.</p>
</div>
<div class="problem-card reveal">
<div class="icon">🔋</div>
<h3>Energy Waste</h3>
<p>Every node transmits on every message — even nodes nowhere near the intended path. Battery-powered devices drain in hours instead of weeks.</p>
</div>
<div class="problem-card reveal">
<div class="icon">💥</div>
<h3>Collision Chaos</h3>
<p>Multiple nodes rebroadcast simultaneously. LoRa is half-duplex — collisions destroy packets, triggering more retransmissions. A vicious cycle.</p>
</div>
<div class="problem-card reveal">
<div class="icon">🛑</div>
<h3>The Hop Limit Wall</h3>
<p>Meshtastic caps hops at 3–7 to prevent flood storms. But this <strong>kills range</strong>: a message can't reach nodes beyond the limit. Every extra hop multiplies transmissions by <em>n</em> — so the limit can't be raised without drowning the network.</p>
</div>
</div>
</section>
<!-- APPROACHES -->
<section id="approaches">
<div class="section-tag reveal">02 — Routing Approaches</div>
<h2 class="section-title reveal">State of the Art vs. New Proposal</h2>
<p class="section-desc reveal">Below we compare four routing strategies on the same 15-node network topology. Each animation runs live in your browser — watch the <strong>TX counter</strong> in each panel. It counts how many radio transmissions are needed to deliver a single message. Fewer TX = less airtime, fewer collisions, longer battery life. The difference is dramatic: from ~100 TX (naive flooding) to ~2 TX (System V6).</p>
<!-- STATE OF THE ART DIVIDER -->
<div class="approach-divider reveal">
<span class="divider-label sota-label">STATE OF THE ART — Meshtastic Today</span>
</div>
<div class="sota-grid">
<!-- NAIVE FLOODING -->
<div class="algo-section flood reveal" id="algo-naive-flood">
<div class="algo-header">
<span class="algo-number sota-badge">BASELINE</span>
<h3 class="algo-name">Naive Flooding</h3>
</div>
<p class="algo-subtitle">The theoretical worst case — every node rebroadcasts every packet exactly once. Meshtastic doesn't actually use this (it uses managed flooding below), but this baseline reveals the fundamental cost of flooding: with n nodes, a single message always costs n transmissions, regardless of distance.</p>
<div class="algo-body">
<div class="algo-canvas-wrap">
<canvas class="algo-canvas" id="canvas-naive-flood"></canvas>
<span class="canvas-label">Live — every node lights up red</span>
</div>
<div class="algo-details">
<h4>How It Works</h4>
<p>Source sends a packet. <strong>Every</strong> receiving node rebroadcasts it once. The entire network participates in every message.</p>
<h4>Cost Per Message</h4>
<p style="font-family:var(--font-display);font-size:1.3rem;color:var(--red);">TX = n <span style="color:var(--text-muted)">(one per node)</span></p>
<div class="pro-con">
<div class="pro"><h5>+ Strengths</h5><ul><li>Maximum reliability</li><li>Zero setup</li></ul></div>
<div class="con"><h5>− Weaknesses</h5><ul><li>O(n) TX per message</li><li>All batteries drain equally</li><li>Collapses at ~40 nodes</li></ul></div>
</div>
</div>
</div>
</div>
<!-- MANAGED FLOODING -->
<div class="algo-section managed reveal" id="algo-managed-flood">
<div class="algo-header">
<span class="algo-number sota-badge">MESHTASTIC CURRENT</span>
<h3 class="algo-name">Managed Flooding</h3>
</div>
<p class="algo-subtitle">This is what Meshtastic actually uses today (v2.6/2.7). It's already quite clever: before rebroadcasting, each node listens briefly. If it hears a neighbor already forwarded the packet, it stays silent (suppression). Nodes far from the sender rebroadcast first (they have lower SNR = shorter contention windows), while close nodes wait and often suppress. Nodes with the ROUTER role always rebroadcast to guarantee backbone coverage. This cuts transmissions by roughly 40–60% compared to naive flooding — a real improvement, but the cost still scales linearly with network size.</p>
<div class="algo-body">
<div class="algo-canvas-wrap">
<canvas class="algo-canvas" id="canvas-managed-flood"></canvas>
<span class="canvas-label">Live — gray nodes = suppressed (saved a TX)</span>
</div>
<div class="algo-details">
<h4>How It Works</h4>
<p>Before rebroadcasting, each node <strong>listens briefly</strong>. If it hears another node already rebroadcast, it <strong>suppresses</strong> its own transmission. Distant nodes (low SNR) get shorter delays and rebroadcast first. Close nodes wait and often suppress.</p>
<p style="margin-top:0.5rem"><strong>ROUTER</strong>-role nodes (marked R) override suppression — they always rebroadcast to ensure backbone coverage.</p>
<h4>Cost Per Message</h4>
<p style="font-family:var(--font-display);font-size:1.3rem;color:var(--yellow);">TX ≈ 0.4n – 0.6n <span style="color:var(--text-muted)">(~50% suppression)</span></p>
<div class="pro-con">
<div class="pro"><h5>+ Strengths</h5><ul><li>~50% less TX than naive</li><li>Self-organizing</li><li>Proven in 100+ node meshes</li></ul></div>
<div class="con"><h5>− Weaknesses</h5><ul><li>Still O(n) per message</li><li>Hop limit still needed</li><li>No path intelligence</li></ul></div>
</div>
</div>
</div>
</div>
<!-- NEXT-HOP ROUTING -->
<div class="algo-section nexthop reveal" id="algo-next-hop">
<div class="algo-header">
<span class="algo-number sota-badge">MESHTASTIC v2.6</span>
<h3 class="algo-name">Next-Hop Routing</h3>
</div>
<p class="algo-subtitle">New in Meshtastic v2.6 — a significant step toward directed routing, but only for direct messages (unicast). The first time you message someone, it floods normally. The system watches which relay node successfully delivered the packet and caches that relay as the "next hop." Subsequent messages go only through that one relay node — a huge TX reduction. But there's no multi-path fallback: if that relay dies, it floods again. And all broadcasts (position beacons, channel messages) still use managed flooding.</p>
<div class="algo-body">
<div class="algo-canvas-wrap">
<canvas class="algo-canvas" id="canvas-next-hop"></canvas>
<span class="canvas-label">Live — watch the 3 phases: learn, direct, fallback</span>
</div>
<div class="algo-details">
<h4>How It Works</h4>
<p><strong>Phase 1:</strong> First message uses managed flooding. The system tracks which node successfully relayed.</p>
<p style="margin-top:0.5rem"><strong>Phase 2:</strong> Subsequent messages go only via the learned <strong>next-hop</strong> node (marked NH). One relay instead of the whole network.</p>
<p style="margin-top:0.5rem"><strong>Phase 3:</strong> If the next-hop dies, the system <strong>falls back</strong> to managed flooding and learns a new relay.</p>
<h4>Limitations</h4>
<p style="color:var(--text-muted)">Only works for <strong>direct messages</strong> (unicast). Broadcasts still use managed flooding. Only learns one hop — not a full path.</p>
<div class="pro-con">
<div class="pro"><h5>+ Strengths</h5><ul><li>Huge TX reduction for DMs</li><li>Graceful fallback</li><li>Backward compatible</li></ul></div>
<div class="con"><h5>− Weaknesses</h5><ul><li>Broadcasts unchanged</li><li>Single relay, not full path</li><li>No load balancing</li></ul></div>
</div>
</div>
</div>
</div>
</div><!-- /.sota-grid -->
<!-- NEW PROPOSAL DIVIDER -->
<div class="approach-divider reveal" style="margin-top:2rem">
<span class="divider-label proposal-label">NEW PROPOSAL — System V6</span>
</div>
<!-- SYSTEM 5 -->
<div class="algo-section winner reveal" id="algo-winner">
<div class="algo-header">
<span class="algo-number proposal-badge">PROPOSED</span>
<h3 class="algo-name">System V6 — Adaptive Load-Balanced Mesh</h3>
</div>
<p class="algo-subtitle">Our proposal: a fundamentally different approach that combines proven networking concepts into one protocol. Nodes self-organize into geographic clusters using GPS geohashes. Within a cluster, every node knows its neighbors via OGMs. Between clusters, border nodes act as bridges. Routes are built incrementally via distance-vector (like B.A.T.M.A.N.), not by running graph algorithms on-device. For unicast: 2 cached routes per destination with weighted selection. For broadcast (~98% of Meshtastic traffic): elected cluster-distributors propagate messages via local mini-floods, not network-wide flooding. All metrics (load, battery) are next-hop only, locally observable from OGMs. OGM intervals adapt to network density (30-180s) for EU868 duty-cycle compliance. The result: <strong>~1 TX per hop</strong> for unicast, <strong>88-99% fewer TX</strong> for broadcast.</p>
<div class="algo-body">
<div class="algo-canvas-wrap">
<canvas class="algo-canvas" id="canvas-system5"></canvas>
<span class="canvas-label">Live — packets follow weighted routes, load bars adapt</span>
</div>
<div class="algo-details">
<h4>Weight Function</h4>
<p style="font-family:var(--font-display);font-size:1.2rem;color:var(--cyan);">W(r) = α·Q(r) + β·(1−Load) + γ·Batt</p>
<p style="font-size:0.8rem;color:var(--text-muted);">Load and Batt = next-hop node only (from OGM)</p>
<h4>Traffic Distribution</h4>
<p style="font-family:var(--font-display);font-size:1.2rem;color:var(--teal);">Share(r) = W(r) / Σ W(all)</p>
<h4>Key Properties</h4>
<ul>
<li>Traffic flows proportionally — good paths get more, not all</li>
<li>Back-pressure: overloaded nodes shed traffic automatically</li>
<li>Battery-aware: low-power nodes get fewer packets</li>
<li>Pheromone decay: unused paths fade, successful paths strengthen</li>
<li>Works for <strong>all message types</strong> — unicast and broadcast</li>
<li><strong>~1 TX per hop</strong> — no hop limit needed</li>
</ul>
<div class="highlight-box" style="margin:1rem 0;padding:1rem 1.2rem;border-color:var(--cyan-dim);background:rgba(34,211,238,0.04);border-radius:8px">
<h4 style="font-family:var(--font-mono);font-size:0.8rem;color:var(--cyan);margin-bottom:0.4rem">vs. Managed Flooding</h4>
<p style="font-size:0.9rem;line-height:1.6">Managed flooding suppresses ~50% of rebroadcasts but still scales as O(n). System V6 routes along <strong>specific paths</strong> — cost scales with <strong>hop count</strong>, not network size. At 100 nodes: managed flood = ~1,500 TX per message, System V6 = ~2 TX.</p>
</div>
<div class="highlight-box" style="margin:1rem 0;padding:1rem 1.2rem;border-color:var(--teal,var(--cyan-dim));background:rgba(20,184,166,0.04);border-radius:8px">
<h4 style="font-family:var(--font-mono);font-size:0.8rem;color:var(--teal);margin-bottom:0.4rem">vs. Next-Hop Routing</h4>
<p style="font-size:0.9rem;line-height:1.6">Next-hop learns a single relay node for direct messages. System V6 maintains <strong>2-3 full paths</strong> with weighted load distribution for <strong>all traffic types</strong>. When a path fails, the next cached path activates instantly — no flooding fallback needed.</p>
</div>
<div class="pro-con">
<div class="pro"><h5>+ Strengths</h5><ul><li>~1 TX/hop unicast (not ~n)</li><li>88-99% broadcast TX savings</li><li>No hop limit needed</li><li>~1.5 KB RAM for routing table</li><li>Adaptive OGM (EU868 compliant)</li></ul></div>
<div class="con"><h5>- Complexity</h5><ul><li>Most complex to implement</li><li>Requires GPS for geo-clustering</li><li>Tuning parameters (α,β,γ)</li></ul></div>
</div>
</div>
</div>
</div>
</section>
<!-- MATHEMATICS -->
<section id="math">
<div class="section-tag reveal">03 — Mathematical Analysis</div>
<h2 class="section-title reveal">Quantitative Comparison</h2>
<p class="section-desc reveal">Intuition says "less flooding = better," but how much better? The formulas below show the exact TX cost per message for each approach. The key variable is <strong>n</strong> (network size): flooding-based approaches scale with n, while directed routing scales with <strong>d</strong> (hop distance). Below the formulas, we score each approach across 7 weighted criteria — from TX efficiency to broadcast support — to provide a fair overall comparison.</p>
<!-- Formulas for each approach -->
<div class="formula-cards-grid">
<div class="formula-card reveal" style="border-color:var(--red-dim)">
<h4>Naive Flooding — TX Cost Per Message</h4>
<div class="formula">
<span class="var">TX</span><sub>naive</sub> <span class="op">=</span> <span class="var">n</span>
</div>
<p class="formula-desc">
Every node rebroadcasts once. At n=100: <strong>100 transmissions</strong> per message. Cost grows linearly with network size.
</p>
</div>
<div class="formula-card reveal" style="border-color:rgba(251,191,36,0.3)">
<h4>Managed Flooding — SNR-Based Suppression</h4>
<div class="formula">
<span class="var">TX</span><sub>managed</sub> <span class="op">=</span> <span class="var">n</span> <span class="op">×</span> (1 <span class="op">−</span> <span class="var">S</span>)
<span style="color:var(--text-muted);font-size:0.9rem"> where S ≈ 0.4–0.6</span>
</div>
<p class="formula-desc">
<em>S</em> = suppression rate (fraction of nodes that hear a rebroadcast and stay silent). Depends on density and SNR distribution. At n=100 with S=0.5: <strong>~50 transmissions</strong>. Still O(n) but ~50% cheaper than naive.
</p>
</div>
<div class="formula-card reveal" style="border-color:rgba(251,146,60,0.3)">
<h4>Next-Hop Routing — Learn & Cache (DMs Only)</h4>
<div class="formula">
<span class="var">TX</span><sub>first</sub> <span class="op">=</span> <span class="var">n</span> <span class="op">×</span> (1 <span class="op">−</span> <span class="var">S</span>)
<span style="color:var(--text-muted);font-size:0.9rem"> </span>
<span class="var">TX</span><sub>cached</sub> <span class="op">=</span> <span class="var">d</span>
</div>
<p class="formula-desc">
First message floods (managed). After learning: <em>d</em> = hop count to destination via cached relay. Amortized cost depends on cache hit rate. <strong>Broadcasts still use managed flooding.</strong>
</p>
</div>
<div class="formula-card reveal" style="border-color:var(--cyan-dim)">
<h4>System V6 — Multi-Path Directed Routing</h4>
<div class="formula">
<span class="var">TX</span><sub>v6</sub> <span class="op">=</span> <span class="var">d</span>
<span style="color:var(--text-muted);font-size:0.9rem"> (hop count, always)</span>
</div>
<p class="formula-desc">
Every message — unicast and broadcast — follows a pre-computed path. Cost = hop count, independent of network size. At n=100, d=2: <strong>2 transmissions</strong>. With fallback: scoped cluster flooding adds O(cluster_size) in worst case.
</p>
</div>
<div class="formula-card reveal" style="border-color:var(--cyan-dim)">
<h4>Route Weight Function — System V6 Load Balancing</h4>
<div class="formula">
<span class="var">W</span>(<span class="var">r</span>) <span class="op">=</span>
<span class="var">α</span> · <span class="var">Q</span>(<span class="var">r</span>)
<span class="op">+</span>
<span class="var">β</span> · (1 <span class="op">−</span> <span class="var">Load</span>(<span class="var">r</span>))
<span class="op">+</span>
<span class="var">γ</span> · <span class="var">Batt</span>(<span class="var">r</span>)
</div>
<p class="formula-desc">
<em>Q</em> = link quality (OGM reception rate), <em>Load</em> = queue pressure, <em>Batt</em> = min battery along route.<br>
Traffic share: Share(r) = W(r) / Σ W(all). Tuning: α=0.4, β=0.35, γ=0.25
</p>
</div>
</div><!-- /.formula-cards-grid -->
<h3 style="font-family:var(--font-mono);font-size:0.9rem;color:var(--text-dim);margin:2rem 0 1rem;letter-spacing:0.1em" class="reveal">SCORING MATRIX (0–10, WEIGHTED)</h3>
<div class="comparison-wrap reveal">
<table class="comparison-table">
<thead>
<tr>
<th>Criterion (Weight)</th>
<th style="color:var(--red)">Naive Flood</th>
<th style="color:var(--yellow)">Managed Flood</th>
<th style="color:var(--orange)">Next-Hop</th>
<th style="color:var(--cyan)">System V6</th>
</tr>
</thead>
<tbody>
<tr><td>TX Cost per Message (20%)</td><td>1</td><td>4</td><td>5</td><td style="color:var(--cyan);font-weight:600">10</td></tr>
<tr><td>Delivery Reliability (20%)</td><td>9</td><td>9</td><td>8</td><td style="color:var(--cyan);font-weight:600">9</td></tr>
<tr><td>Scalability (15%)</td><td>1</td><td>3</td><td>4</td><td style="color:var(--cyan);font-weight:600">9</td></tr>
<tr><td>Fault Tolerance (15%)</td><td>8</td><td>8</td><td>7</td><td style="color:var(--cyan);font-weight:600">9</td></tr>
<tr><td>Hop Limit Freedom (10%)</td><td>1</td><td>2</td><td>3</td><td style="color:var(--cyan);font-weight:600">10</td></tr>
<tr><td>Energy Efficiency (10%)</td><td>1</td><td>3</td><td>5</td><td style="color:var(--cyan);font-weight:600">8</td></tr>
<tr><td>Broadcast Support (10%)</td><td>10</td><td>10</td><td>3</td><td style="color:var(--cyan);font-weight:600">9</td></tr>
<tr class="winner-row" style="border-top:2px solid var(--cyan-dim)">
<td style="font-size:0.95rem">WEIGHTED TOTAL</td>
<td style="color:var(--red)">4.3</td>
<td style="color:var(--yellow)">5.5</td>
<td style="color:var(--orange)">5.1</td>
<td style="color:var(--cyan);font-size:1.1rem;font-weight:700">9.2</td>
</tr>
</tbody>
</table>
</div>
<h3 style="font-family:var(--font-mono);font-size:0.9rem;color:var(--text-dim);margin:2rem 0 1rem;letter-spacing:0.1em" class="reveal">FINAL SCORES</h3>
<div class="bar-chart reveal" id="bar-chart">
<div class="bar-col">
<div class="bar" data-score="4.3" style="height:0;background:var(--red)"><span class="bar-value" style="color:var(--red)">4.3</span></div>
<span class="bar-label">Naive Flood</span>
</div>
<div class="bar-col">
<div class="bar" data-score="5.5" style="height:0;background:var(--yellow)"><span class="bar-value" style="color:var(--yellow)">5.5</span></div>
<span class="bar-label">Managed Flood</span>
</div>
<div class="bar-col">
<div class="bar" data-score="5.1" style="height:0;background:var(--orange)"><span class="bar-value" style="color:var(--orange)">5.1</span></div>
<span class="bar-label">Next-Hop</span>
</div>
<div class="bar-col">
<div class="bar" data-score="9.2" style="height:0;background:var(--cyan)"><span class="bar-value" style="color:var(--cyan)">9.2</span></div>
<span class="bar-label">System V6</span>
</div>
</div>
</section>
<!-- WINNER ARCHITECTURE -->
<section id="winner">
<div class="section-tag reveal">04 — System V6 Architecture</div>
<h2 class="section-title reveal">What System V6 Adds Beyond Managed Flooding</h2>
<p class="section-desc reveal">Meshtastic's managed flooding is clever — but still O(n). We didn't invent new theory. Instead, System V6 borrows six <strong>proven, battle-tested concepts</strong> from decades of networking research and adapts them to LoRa's unique constraints (low bandwidth, half-duplex, 1% duty cycle, limited RAM). Each concept solves a specific piece of the puzzle:</p>
<div class="arch-grid">
<div class="arch-card reveal">
<div class="source">from Internet Routing</div>
<h4>OSPF Areas <span class="arrow">→</span> Geo-Clusters</h4>
<p>Nodes self-organize by geohash prefix. Full topology within cluster, summarized routes between. Scales from 10 to 10,000+ nodes.</p>
</div>
<div class="arch-card reveal">
<div class="source">from Freifunk / B.A.T.M.A.N.</div>
<h4>OGM Counting <span class="arrow">→</span> Quality Metric</h4>
<p>Periodic originator messages. Count reception rate per neighbor. No complex calculation — just count how many arrive.</p>
</div>
<div class="arch-card reveal">
<div class="source">from Data Centers</div>
<h4>Weighted ECMP <span class="arrow">→</span> Load Balancing</h4>
<p>Traffic distributed proportionally to route weight. Good paths get more traffic, but never all. No single bottleneck node.</p>
</div>
<div class="arch-card reveal">
<div class="source">from Network Theory</div>
<h4>Back-Pressure <span class="arrow">→</span> Congestion Control</h4>
<p>Overloaded nodes report queue pressure. Traffic naturally avoids congested paths — like water flowing around rocks.</p>
</div>
<div class="arch-card reveal">
<div class="source">from Ant Colony Optimization</div>
<h4>Pheromone Decay <span class="arrow">→</span> Self-Optimization</h4>
<p>Successful deliveries strengthen a route. Timeouts weaken it. Unused routes fade naturally. The network learns.</p>
</div>
<div class="arch-card reveal">
<div class="source">from DNS</div>
<h4>Hierarchical Cache <span class="arrow">→</span> Node Discovery</h4>
<p>Where is the target node? Ask locally first, then cluster, then region. Answers are cached. Scoped flooding only as last resort.</p>
</div>
</div>
</section>
<!-- v2.0 FEATURES — BUILT FROM REAL-WORLD FEEDBACK -->
<section id="v2-features">
<div class="section-tag reveal">05 — v2.0 Features (Built from Bay Area Mesh Feedback)</div>
<h2 class="section-title reveal">What Real-World Testing Revealed</h2>
<p class="section-desc reveal">Feedback from <a href="docs/bay-area-feedback-response.md" style="color:var(--cyan)">Bay Area Mesh operators</a> exposed critical gaps in the original design. Their mountaintop routers (SUNL, Mt Diablo) showed that half-duplex radio physics — not routing algorithms — is the true scaling bottleneck. Five features were built in direct response.</p>
<div class="arch-grid">
<div class="arch-card reveal" style="border-color:var(--cyan-dim)">
<div class="source">from Bay Area Feedback</div>
<h4>Node Silencing <span class="arrow">→</span> Collision Reduction</h4>
<p>The network identifies <strong>redundant nodes</strong> (those whose neighbors are all reachable via other paths) and mutes them. Silenced nodes still <strong>listen</strong> — they receive messages, the network knows they exist — but they don't rebroadcast. This removes the collision noise at mountaintops. Battery-fair rotation every 10 minutes. Result: <strong>TX halved, only 3% less delivery.</strong></p>
</div>
<div class="arch-card reveal" style="border-color:var(--cyan-dim)">
<div class="source">from Bay Area Feedback</div>
<h4>Half-Duplex Radio Model <span class="arrow">→</span> Realistic Simulation</h4>
<p>LoRa radios are half-duplex: a node <strong>cannot TX while receiving</strong>. When a mountaintop hears 10 rebroadcasts, it's blocked from forwarding for 10-20 seconds. Our simulator now models this per-node radio state (IDLE/TX/RX) on <strong>ALL scenarios</strong>. Result: flooding collapses to <strong>0–60% delivery</strong> across all scenarios (~87% → ~6% in Bay Area). System V6 holds at <strong>~74%</strong> in Bay Area and maintains high delivery everywhere.</p>
</div>
<div class="arch-card reveal" style="border-color:var(--cyan-dim)">
<div class="source">from Bay Area Feedback</div>
<h4>Sequence Numbers <span class="arrow">→</span> Gap Detection</h4>
<p>Multi-path routing can deliver messages out of order (A,B,C → C,B,A via 3 paths). A <strong>2-byte sequence counter</strong> per (source, destination) pair in the packet header lets the app detect gaps: "got seq 3 and 5, missed 4." Zero extra TX cost — just 2 bytes added to the existing header.</p>
</div>
<div class="arch-card reveal" style="border-color:var(--cyan-dim)">
<div class="source">from Bay Area Feedback</div>
<h4>Emergency Re-Route <span class="arrow">→</span> Fewer Fallback Floods</h4>
<p>When both cached routes fail, System V6 falls back to <strong>scoped corridor flooding</strong> (source + destination clusters + border nodes only). Routes are built via distance-vector from OGM data — no BFS computation on-device needed.</p>
</div>
<div class="arch-card reveal" style="border-color:var(--cyan-dim)">
<div class="source">from Bay Area Feedback</div>
<h4>3-Tier Topology <span class="arrow">→</span> Real-World Scenarios</h4>
<p>A new <strong>Bay Area simulation</strong> models the actual network structure: 7 mountaintop nodes (45km range), 35 hill/rooftop nodes (10km), 193 valley/indoor nodes (2.5km). Asymmetric links, half-duplex, collision capture. Four Bay Area scenarios test normal, stress, silencing, and combined conditions. <a href="simulator.html" style="color:var(--cyan)">Try it live →</a></p>
</div>
</div>
<!-- Node Silencing Results -->
<div class="highlight-box cyan reveal" style="margin:2rem auto;max-width:800px;padding:1.5rem 2rem;border:1px solid var(--cyan-dim);background:rgba(34,211,238,0.04);border-radius:12px">
<h4 style="font-family:var(--font-mono);font-size:0.85rem;color:var(--cyan);margin-bottom:0.8rem">Bay Area Results — Half-Duplex + Node Silencing (averaged over 5 random seeds)</h4>
<table style="width:100%;font-family:var(--font-mono);font-size:0.82rem;border-collapse:collapse">
<tr style="color:var(--text-muted);font-size:0.7rem;text-transform:uppercase;letter-spacing:0.05em">
<td style="padding:0.3rem 0">Scenario</td>
<td style="text-align:right;color:var(--yellow)">Flood Del.</td>
<td style="text-align:right;color:var(--cyan)">S5 Del.</td>
<td style="text-align:right;color:var(--cyan)">S5 TX</td>
<td style="text-align:right">Silent</td>
</tr>
<tr style="border-top:1px solid var(--border)">
<td style="padding:0.4rem 0;color:var(--text)">Bay Area (no half-duplex)</td>
<td style="text-align:right;color:var(--green)">~87%</td>
<td style="text-align:right;color:var(--green)">~80%</td>
<td style="text-align:right;color:var(--cyan)">~47K</td>
<td style="text-align:right;color:var(--text-muted)">—</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">Bay Area (half-duplex)</td>
<td style="text-align:right;color:var(--red);font-weight:700">~6%</td>
<td style="text-align:right;color:var(--green)">~74%</td>
<td style="text-align:right;color:var(--orange)">~516K</td>
<td style="text-align:right;color:var(--text-muted)">0%</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text);font-weight:600">Bay Area + Silencing</td>
<td style="text-align:right;color:var(--red);font-weight:700">~6%</td>
<td style="text-align:right;color:var(--green)">~70%</td>
<td style="text-align:right;color:var(--cyan);font-weight:600">~284K</td>
<td style="text-align:right;color:var(--cyan)">57%</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">Bay Area + Stress</td>
<td style="text-align:right;color:var(--red);font-weight:700">~5%</td>
<td style="text-align:right;color:var(--yellow)">~55%</td>
<td style="text-align:right;color:var(--orange)">~283K</td>
<td style="text-align:right;color:var(--text-muted)">0%</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">Bay Area + Silencing + Stress</td>
<td style="text-align:right;color:var(--red);font-weight:700">~5%</td>
<td style="text-align:right;color:var(--yellow)">~49%</td>
<td style="text-align:right;color:var(--cyan)">~132K</td>
<td style="text-align:right;color:var(--cyan)">57%</td>
</tr>
</table>
<p style="margin-top:0.6rem;font-size:0.85rem;color:var(--text-dim);line-height:1.6"><strong style="color:var(--cyan)">Key insight:</strong> Half-duplex destroys flooding in Bay Area (~87% → ~6%) and across ALL scenarios (0–60% delivery). System V6 holds at ~74% in Bay Area and is the only approach maintaining high delivery. Node Silencing halves TX cost (~516K → ~284K) with only ~4% less delivery. 128 of 193 valley nodes are muted — all 7 mountain nodes stay active. Results averaged over 5 random seeds for statistical reliability.</p>
</div>
</section>
<!-- HOP COST — THE KILLER ARGUMENT -->
<section id="hop-cost" class="hop-cost-section">
<div class="section-tag reveal">06 — The Killer Argument</div>
<h2 class="section-title reveal">Why Hop Limits Become Irrelevant</h2>
<p class="section-desc reveal">In flooding, every hop multiplies transmissions across the <em>entire</em> network. In System V6, every hop costs exactly <strong>one transmission</strong>. This single change unlocks everything.</p>
<div class="hop-comparison reveal">
<div class="hop-card hop-flooding">
<h4 style="color:var(--red)">Flooding: Cost per Hop = <em>n</em></h4>
<div class="hop-formula" style="color:var(--red)">TX<sub>total</sub> = n × hops</div>
<p>Every node rebroadcasts at every hop. At 100 nodes and 5 hops, a single message generates <strong>330,000+ transmissions</strong>. The hop limit (default 3) is a survival mechanism — without it, the network drowns.</p>
<div class="hop-example">
<div class="hop-step">Hop 1: <strong>100 TX</strong></div>
<div class="hop-step">Hop 2: <strong>100 TX</strong></div>
<div class="hop-step">Hop 3: <strong>100 TX</strong></div>
<div class="hop-step hop-wall">Hop 4: <strong>BLOCKED</strong> (hop limit)</div>
</div>
</div>
<div class="hop-card hop-system5">
<h4 style="color:var(--cyan)">System V6: Cost per Hop = <em>1</em></h4>
<div class="hop-formula" style="color:var(--cyan)">TX<sub>total</sub> = hops</div>
<p>Only the forwarding node transmits. At 100 nodes and 5 hops, a single message generates <strong>5 transmissions</strong>. No hop limit needed — 20 hops cost the same as flooding costs for 1.</p>
<div class="hop-example">
<div class="hop-step hop-s5">Hop 1: <strong>1 TX</strong></div>
<div class="hop-step hop-s5">Hop 2: <strong>1 TX</strong></div>
<div class="hop-step hop-s5">Hop 3: <strong>1 TX</strong></div>
<div class="hop-step hop-s5">Hop 4: <strong>1 TX</strong></div>
<div class="hop-step hop-s5">Hop 5: <strong>1 TX</strong></div>
<div class="hop-step hop-s5" style="opacity:0.6">...</div>
<div class="hop-step hop-s5">Hop 20: <strong>1 TX</strong></div>
</div>
</div>
</div>
<!-- Proof from simulation -->
<div class="highlight-box cyan reveal" style="margin:2rem auto;max-width:800px;padding:1.5rem 2rem;border:1px solid var(--cyan-dim);background:rgba(34,211,238,0.04);border-radius:12px">
<h4 style="font-family:var(--font-mono);font-size:0.85rem;color:var(--cyan);margin-bottom:0.8rem">Verified by Simulation (Realistic Hop Limits)</h4>
<table style="width:100%;font-family:var(--font-mono);font-size:0.82rem;border-collapse:collapse">
<tr style="color:var(--text-muted);font-size:0.7rem;text-transform:uppercase;letter-spacing:0.05em">
<td style="padding:0.3rem 0">Scenario</td>
<td style="text-align:right">Nodes</td>
<td style="text-align:right;color:var(--red)">3-hop Del.</td>
<td style="text-align:right;color:var(--orange)">5-hop Del.</td>
<td style="text-align:right;color:var(--yellow)">7-hop Del.</td>
<td style="text-align:right;color:var(--cyan)">Sys5 Del.</td>
<td style="text-align:right;color:var(--cyan)">Sys5 TX</td>
</tr>
<tr style="border-top:1px solid var(--border)">
<td style="padding:0.4rem 0;color:var(--text)">Small Local</td>
<td style="text-align:right">20</td>
<td style="text-align:right;color:var(--yellow)">87%</td>
<td style="text-align:right;color:var(--yellow)">87%</td>
<td style="text-align:right;color:var(--yellow)">87%</td>
<td style="text-align:right;color:var(--green)">100%</td>
<td style="text-align:right;color:var(--cyan)">115</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">Medium City</td>
<td style="text-align:right">100</td>
<td style="text-align:right;color:var(--red);font-weight:700">25%</td>
<td style="text-align:right;color:var(--red)">27%</td>
<td style="text-align:right;color:var(--red)">27%</td>
<td style="text-align:right;color:var(--green)">100%</td>
<td style="text-align:right;color:var(--cyan)">402</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">Large Regional</td>
<td style="text-align:right">500</td>
<td style="text-align:right;color:var(--red);font-weight:700">1%</td>
<td style="text-align:right;color:var(--red);font-weight:700">2%</td>
<td style="text-align:right;color:var(--red);font-weight:700">3%</td>
<td style="text-align:right;color:var(--yellow)">76%</td>
<td style="text-align:right;color:var(--cyan)">412k</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">1000 Nodes</td>
<td style="text-align:right">1000</td>
<td style="text-align:right;color:var(--red);font-weight:700">0%</td>
<td style="text-align:right;color:var(--red);font-weight:700">0%</td>
<td style="text-align:right;color:var(--red);font-weight:700">0%</td>
<td style="text-align:right;color:var(--orange)">46%</td>
<td style="text-align:right;color:var(--orange)">182k*</td>
</tr>
<tr style="border-top:1px solid rgba(42,54,84,0.5)">
<td style="padding:0.4rem 0;color:var(--text)">1500 Nodes</td>
<td style="text-align:right">1500</td>
<td style="text-align:right;color:var(--red);font-weight:700">0%</td>
<td style="text-align:right;color:var(--red);font-weight:700">1%</td>
<td style="text-align:right;color:var(--red);font-weight:700">1%</td>
<td style="text-align:right;color:var(--orange)">44%</td>
<td style="text-align:right;color:var(--orange)">197k*</td>
</tr>
</table>
<p style="margin-top:0.6rem;font-size:0.75rem;color:var(--text-muted)">* At 1000+ nodes, System V6 uses <strong>more total TX</strong> than managed flooding — but delivers <strong>46% vs 0%</strong>. Managed flooding is effectively dead at this scale with half-duplex enabled.</p>
<p style="margin-top:0.6rem;font-size:0.85rem;color:var(--text-dim);line-height:1.6"><strong style="color:var(--red)">Critical finding:</strong> With half-duplex and collisions enabled on ALL scenarios, managed flooding's delivery rate <strong>collapses everywhere</strong>. At 1000 nodes, <strong>0%</strong> of messages arrive. Even at 100 nodes, only <strong>27%</strong>. System V6 delivers <strong>100% at 100 nodes and 46% at 1000 nodes</strong>. Half-duplex radio physics — not just hop limits — make flooding <strong>fundamentally unreliable</strong>.</p>
</div>
<div class="problem-grid" style="margin-top:2rem">
<div class="problem-card reveal" style="border-color:var(--cyan-dim)">
<div class="icon" style="background:rgba(34,211,238,0.1);color:var(--cyan)">📶</div>
<h3>Unlimited Range</h3>
<p>No more artificial hop limits. Messages can traverse <strong>20, 30, or 50 hops</strong> at the same per-hop cost. The network's range is limited only by node density, not by protocol constraints.</p>
</div>
<div class="problem-card reveal" style="border-color:var(--cyan-dim)">
<div class="icon" style="background:rgba(34,211,238,0.1);color:var(--cyan)">🔋</div>
<h3>Battery Independence</h3>
<p>Only the forwarding node transmits per hop — not every node in range. Nodes <strong>far from the path sleep through</strong>. Battery life increases from hours to weeks.</p>
</div>
<div class="problem-card reveal" style="border-color:var(--cyan-dim)">
<div class="icon" style="background:rgba(34,211,238,0.1);color:var(--cyan)">📡</div>
<h3>Preset Freedom</h3>
<p>With cheap hops, <strong>SHORT_FAST with more hops</strong> works as well as LONG_SLOW with fewer hops — at higher data rates. Choose the preset for your local conditions, not for the network's range limit.</p>
</div>
</div>
</section>
<!-- METRICS -->
<section id="metrics">
<div class="section-tag reveal">07 — Key Metrics</div>
<h2 class="section-title reveal">System V6 by the Numbers</h2>
<div class="metrics-row">
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-reliability">0</span><span class="unit">%</span></div>
<div class="metric-label">Delivery Reliability</div>
</div>
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-reduction">0</span><span class="unit">%</span></div>
<div class="metric-label">Bandwidth Reduction vs Flood</div>
</div>
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-failover">0</span><span class="unit">ms</span></div>
<div class="metric-label">Failover Time</div>
</div>
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-overhead">0</span><span class="unit">B</span></div>
<div class="metric-label">Piggyback Overhead</div>
</div>
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-table">0</span></div>
<div class="metric-label">Routing Table Entries (n=1000)</div>
</div>
<div class="metric-card reveal">
<div class="metric-value"><span id="counter-score">0</span><span class="unit">/10</span></div>
<div class="metric-label">Weighted Score</div>
</div>
</div>
</section>
<!-- NETWORK FORMATION -->
<section id="formation" class="formation-section">
<div class="section-tag reveal">08 — Network Formation</div>
<h2 class="section-title reveal">How the Network Builds Itself</h2>
<p class="section-desc reveal">No central server, no configuration, no coordination. When nodes power on, they independently discover neighbors via OGM beacons (every 30 seconds), compute their geographic cluster from GPS, identify border nodes that bridge clusters, and build multi-path routing tables — all automatically. Click "Next Step" below to watch this process unfold. Each step shows exactly what happens in the firmware. <a href="how-it-works.html" style="color:var(--cyan)">For the full technical deep-dive, see How It Works →</a></p>
<div class="formation-wrap reveal">
<div class="formation-canvas-wrap">
<canvas id="canvas-formation"></canvas>
</div>
<div class="formation-controls">
<div class="formation-step-info">
<div class="formation-step-num" id="form-step-num">Step 0 / 9</div>
<h4 class="formation-step-title" id="form-step-title">Press "Next Step" to begin</h4>
<p class="formation-step-desc" id="form-step-desc">This animation shows how a System V6 mesh network self-organizes from powered-on nodes to a fully routed, load-balanced mesh.</p>
</div>
<div class="formation-btns">
<button id="form-btn-prev" class="form-btn" disabled>◀ Back</button>
<button id="form-btn-next" class="form-btn form-btn-primary">Next Step ▶</button>
<button id="form-btn-reset" class="form-btn">Reset</button>
</div>
<div class="formation-log" id="form-log"></div>
</div>
</div>
</section>
<!-- SCALE SCENARIOS -->
<section id="scenarios" class="scale-scenarios">
<div class="section-tag reveal">09 — Real-World Scale</div>
<h2 class="section-title reveal">From Neighborhood to Worldwide</h2>
<p class="section-desc reveal">Mesh networks don't exist in a vacuum — they range from a dozen handhelds in a neighborhood to thousands of devices spanning continents. System V6's geo-clustering architecture naturally adapts: a single cluster handles local traffic efficiently, while inter-cluster routing via border nodes scales to arbitrarily large networks. The three live simulations below show how the same protocol handles neighborhood, continental, and global scale. Watch the node activity logs on the right — they show real-time routing decisions, OGM beacons, and failover events.</p>
<!-- LOCAL -->
<div class="scenario reveal" id="scn-local">
<div class="scenario-header">
<span class="scenario-badge">LOCAL</span>
<h3 class="scenario-name">Neighborhood Mesh — Munich District</h3>
</div>
<p class="scenario-desc">12 nodes within ~3km. Direct LoRa links. Single geo-cluster. Full internal topology known to all nodes. Multi-path routing with load balancing.</p>
<div class="scenario-canvas-wrap">
<canvas class="scenario-canvas" id="canvas-local"></canvas>
<div class="scenario-legend">
<span class="lg-dot" style="background:var(--cyan)"></span>Active node<br>
<span class="lg-dot" style="background:var(--green)"></span>Packet (primary)<br>
<span class="lg-dot" style="background:var(--teal)"></span>Packet (secondary)<br>
<span class="lg-dot" style="background:var(--yellow)"></span>OGM beacon<br>
<span class="lg-dot" style="background:var(--orange)"></span>Back-pressure
</div>
<div class="node-panel" id="panel-local">
<h5>Node Activity Log</h5>
<div id="panel-local-content"><div style="color:var(--text-muted);font-size:0.6rem;padding:4px 0">Waiting for simulation...</div></div>
</div>
<div class="scenario-stats">
<div class="scenario-stat">Nodes: <span class="sv">12</span></div>
<div class="scenario-stat">Range: <span class="sv">~3 km</span></div>
<div class="scenario-stat">Clusters: <span class="sv">1</span></div>
<div class="scenario-stat">Avg hops: <span class="sv">2.1</span></div>
<div class="scenario-stat">Latency: <span class="sv">~200ms</span></div>
</div>
</div>
</div>
<!-- EUROPE -->
<div class="scenario reveal" id="scn-europe">
<div class="scenario-header">
<span class="scenario-badge">CONTINENTAL</span>
<h3 class="scenario-name">Europe-Wide — Cross-Cluster Routing</h3>
</div>
<p class="scenario-desc">Clusters in major cities connected via MQTT gateways and long-range relays. Border nodes bridge clusters. DNS-like cache resolves node positions.</p>
<div class="scenario-canvas-wrap">
<canvas class="scenario-canvas" id="canvas-europe"></canvas>
<div class="scenario-legend">
<span class="lg-dot" style="background:var(--purple)"></span>Cluster (city)<br>
<span class="lg-dot" style="background:var(--cyan)"></span>Gateway<br>
<span class="lg-dot" style="background:var(--green)"></span>Data packet<br>
<span class="lg-dot" style="background:var(--yellow)"></span>DNS query<br>
<span class="lg-dot" style="background:var(--orange)"></span>MQTT bridge
</div>
<div class="node-panel" id="panel-europe">
<h5>Cross-Cluster Protocol</h5>
<div id="panel-europe-content"><div style="color:var(--text-muted);font-size:0.6rem;padding:4px 0">Waiting for simulation...</div></div>
</div>
<div class="scenario-stats">
<div class="scenario-stat">Clusters: <span class="sv">8</span></div>
<div class="scenario-stat">Total nodes: <span class="sv">~2400</span></div>
<div class="scenario-stat">Bridge: <span class="sv">MQTT+LoRa</span></div>
<div class="scenario-stat">Cluster hops: <span class="sv">3-5</span></div>
<div class="scenario-stat">Latency: <span class="sv">~2-8s</span></div>
</div>
</div>
</div>
<!-- GLOBAL -->
<div class="scenario reveal" id="scn-global">
<div class="scenario-header">
<span class="scenario-badge">WORLDWIDE</span>
<h3 class="scenario-name">Global Mesh — Continent-Spanning Network</h3>
</div>
<p class="scenario-desc">Continental super-clusters connected via internet backbone (MQTT). Hierarchical geohash addressing. Cascading DNS cache for node discovery.</p>
<div class="scenario-canvas-wrap">
<canvas class="scenario-canvas" id="canvas-global"></canvas>
<div class="scenario-legend">
<span class="lg-dot" style="background:var(--orange)"></span>Super-cluster<br>
<span class="lg-dot" style="background:var(--cyan)"></span>Regional gateway<br>
<span class="lg-dot" style="background:var(--green)"></span>Data packet<br>
<span class="lg-dot" style="background:var(--yellow)"></span>DNS cascade<br>
<span class="lg-dot" style="background:rgba(255,255,255,0.4)"></span>Internet backbone
</div>
<div class="node-panel" id="panel-global">
<h5>Global Routing Protocol</h5>
<div id="panel-global-content"><div style="color:var(--text-muted);font-size:0.6rem;padding:4px 0">Waiting for simulation...</div></div>
</div>
<div class="scenario-stats">
<div class="scenario-stat">Continents: <span class="sv">5</span></div>
<div class="scenario-stat">Super-clusters: <span class="sv">24</span></div>
<div class="scenario-stat">Total nodes: <span class="sv">~50,000</span></div>
<div class="scenario-stat">Max hops: <span class="sv">12-18</span></div>
<div class="scenario-stat">Latency: <span class="sv">5-30s</span></div>
</div>
</div>
</div>
</section>
<!-- RESILIENCE & ADAPTIVE QoS -->
<section id="resilience" class="resilience-section">
<div class="section-tag reveal">10 — Resilience & Adaptive QoS</div>
<h2 class="section-title reveal">When Things Go Wrong</h2>
<p class="section-desc reveal">A routing protocol that only works in perfect conditions is worthless. In the real world, nodes die (batteries, hardware), GPS signals drop, internet links fail, and entire regions go dark. System V6 is designed to degrade gracefully: multi-path routing provides instant failover (0ms — the next cached route is already known), scoped corridor flooding is the safety net, and the adaptive QoS gate ensures emergency messages always get through even when the network is collapsing. Click on nodes or links below to simulate failures and watch the network adapt in real-time.</p>
<!-- Failure case explanation cards -->
<div class="problem-grid" style="margin-bottom:2.5rem">
<div class="problem-card reveal" style="border-color:var(--red-dim)">
<div class="icon" style="background:rgba(248,113,113,0.1);color:var(--red)">⚠</div>
<h3>Node Failure</h3>
<p>A node dies (battery, hardware). Its routes break instantly. System V6 switches to <strong>cached backup routes in 0ms</strong>. If a border node dies, the second border node takes over. If all borders die, the cluster falls back to flooding.</p>
</div>
<div class="problem-card reveal" style="border-color:var(--orange-dim)">
<div class="icon" style="background:rgba(251,146,60,0.1);color:var(--orange)">📡</div>
<h3>GPS Failure</h3>
<p>GPS module fails or loses signal. The node can't compute its geohash. <strong>Fallback: neighbor consensus</strong> — if 4 of 5 neighbors say "u0x8", the node adopts that cluster. If no neighbors have GPS: "homeless" mode with local flooding.</p>
</div>
<div class="problem-card reveal" style="border-color:var(--yellow)">
<div class="icon" style="background:rgba(251,191,36,0.1);color:var(--yellow)">🌐</div>
<h3>MQTT Bridge Down</h3>
<p>Internet-based MQTT links between cities fail. The <strong>LoRa relay subnet activates</strong> — a chain of small relay nodes bridges clusters via pure radio. Slower (more hops) but functional. The green chain below the clusters is this backup path.</p>
</div>
<div class="problem-card reveal" style="border-color:var(--cyan-dim)">
<div class="icon" style="background:rgba(34,211,238,0.1);color:var(--cyan)">♥</div>
<h3>Adaptive QoS</h3>
<p>As the Network Health Score drops, low-priority traffic is automatically blocked. <strong>SOS (P0) always gets through</strong>, even at 1% network health. Firmware updates (P7) only when the network is perfect. The network breathes: less traffic under stress = self-healing.</p>
</div>
</div>
<div class="resilience-wrap reveal">
<!-- Main interactive canvas -->
<div class="resilience-canvas-wrap">
<canvas id="canvas-resilience"></canvas>
<div class="resilience-hint">Click nodes or links to toggle failure • Dashed yellow = MQTT • Dashed green = LoRa relay chain</div>
</div>
<!-- Right panel -->
<div class="resilience-panel">
<!-- Per-Cluster NHS -->
<div class="nhs-gauge-wrap">
<h5>Local NHS (per Cluster)</h5>
<div class="nhs-cluster-list" id="nhs-cluster-list"></div>
<div class="nhs-gauge" style="margin-top:0.5rem">
<canvas id="canvas-nhs" width="180" height="100"></canvas>
<div class="nhs-value" id="nhs-value">1.00</div>
<div class="nhs-level" id="nhs-level">GREEN</div>
</div>
<div style="font-family:var(--font-mono);font-size:0.55rem;color:var(--text-muted);text-align:center;margin-top:2px">Worst cluster shown on gauge</div>
<div class="nhs-components" id="nhs-components"></div>
</div>
<!-- QoS Gate -->
<div class="qos-gate-wrap">
<h5>QoS Priority Gate</h5>
<div class="qos-classes" id="qos-classes"></div>
</div>
<!-- Failure Buttons -->
<div class="failure-presets">
<h5>Failure Presets</h5>
<button class="fail-btn" id="fail-reset">Reset All</button>
<button class="fail-btn" id="fail-node">Kill Random Node</button>
<button class="fail-btn" id="fail-border">Kill Border Node</button>
<button class="fail-btn" id="fail-gps">GPS Failure</button>
<button class="fail-btn" id="fail-mqtt">MQTT Bridge Down</button>
<button class="fail-btn" id="fail-internet">Full Internet Down</button>
<button class="fail-btn" id="fail-cascade">Cascade (3 nodes)</button>
</div>
<!-- Event Log -->
<div class="resilience-log" id="res-log"></div>
</div>
</div>
</section>
<!-- SIMULATION RESULTS -->
<section id="sim-results" class="sim-results-section">
<div class="section-tag reveal">11 — Simulation Results</div>
<h2 class="section-title reveal">Real Numbers from the Simulator</h2>
<p class="section-desc reveal">Claims are only as good as their evidence. We built a <strong>Python simulator</strong> that models EU 868MHz LoRa physics (path loss, terrain, duty cycle, collisions, half-duplex radio) and runs 6 routers on identical networks: Naive Flood, Managed Flood at 3/5/7 hop limits, Next-Hop, and System V6. Each scenario runs 100–300 random messages and measures delivery rate, total transmissions, and per-node load. The results below are from 26 scenarios covering 20–1500 nodes — including realistic environments (rural, maritime, indoor, highway convoy) and stress tests (node failure, link degradation, duty cycle enforcement). <a href="simulator.html" style="color:var(--cyan)">Try the interactive simulator →</a></p>
<!-- Category Filter -->
<div class="sim-filter reveal" style="display:flex;gap:0.4rem;flex-wrap:wrap;margin-bottom:1.2rem;justify-content:center">
<button class="sim-filter-btn active" data-cat="all" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--cyan-dim);background:var(--cyan-glow);color:var(--cyan);border-radius:6px;cursor:pointer">All</button>
<button class="sim-filter-btn" data-cat="scale" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Scale</button>
<button class="sim-filter-btn" data-cat="stress" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Stress</button>
<button class="sim-filter-btn" data-cat="topology" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Terrain</button>
<button class="sim-filter-btn" data-cat="mobility" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Mobile</button>
<button class="sim-filter-btn" data-cat="dense" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Dense/Large</button>
<button class="sim-filter-btn" data-cat="bay_area" style="font-family:var(--font-mono);font-size:0.75rem;padding:0.3rem 0.8rem;border:1px solid var(--border);background:transparent;color:var(--text-dim);border-radius:6px;cursor:pointer">Bay Area</button>
</div>
<!-- Summary Table -->
<div class="sim-table-wrap reveal">
<table class="sim-table">
<thead>
<tr>
<th>Scenario</th>
<th>Nodes</th>
<th style="color:var(--red)">Naive TX</th>
<th style="color:var(--yellow)">Managed TX</th>
<th style="color:var(--orange)">Next-Hop TX</th>
<th style="color:var(--cyan)">Sys5 TX</th>
<th style="color:var(--cyan)">S5 Delivery</th>
<th>S5 vs Managed</th>
</tr>
</thead>
<tbody id="sim-table-body"></tbody>
</table>
</div>
<!-- Charts Grid -->
<div class="sim-charts-grid">
<div class="sim-chart-card reveal">
<h4>Transmissions: Flooding vs System V6 <button id="btn-scale-toggle" class="scale-toggle-btn">Switch to Linear</button></h4>
<p class="chart-subtitle">Click button to toggle between log and linear scale</p>
<div class="sim-chart-wrap">
<canvas id="chart-bandwidth"></canvas>
</div>
</div>
<div class="sim-chart-card reveal">
<h4>Delivery Rate Under Stress</h4>
<p class="chart-subtitle">System V6 maintains high delivery even under failures</p>
<div class="sim-chart-wrap">
<canvas id="chart-delivery"></canvas>
</div>
</div>
<div class="sim-chart-card reveal">
<h4>Busiest Node (Max TX Load)</h4>
<p class="chart-subtitle">How much the most loaded node has to transmit — lower is better</p>
<div class="sim-chart-wrap">
<canvas id="chart-load"></canvas>
</div>
</div>
<div class="sim-chart-card reveal">
<h4>QoS Priority Gate (Stress Test)</h4>
<p class="chart-subtitle">High-priority traffic gets through even when the network is degraded</p>
<div class="sim-chart-wrap">
<canvas id="chart-qos"></canvas>
</div>
</div>
</div>
<!-- Key insight -->
<div class="tldr-card reveal" style="margin-top:2rem">
<p class="tldr-text">With <strong>realistic hop limits (3–7)</strong>, managed flooding not only wastes bandwidth — it <strong>fails to deliver</strong>. At 500 nodes with hop limit 7, only <strong>51%</strong> of messages arrive. At 1000 nodes, only <strong>6%</strong>. System V6 delivers <strong>7.5x more messages</strong> in the same scenarios, using fewer total transmissions per delivered message. The hop limit is not a safety net — it is the <strong>primary scaling barrier</strong> that makes large mesh networks fundamentally unreliable.</p>
</div>
</section>
<!-- GLOSSARY -->
<section id="glossary">
<div class="section-tag reveal">12 — Glossary</div>
<h2 class="section-title reveal">Key Terms Explained</h2>
<p class="section-desc reveal">Mesh networking spans radio engineering, graph theory, and protocol design. Here's a quick reference for the technical terms used throughout this presentation — from LoRa basics to the protocol-specific concepts introduced by System V6.</p>
<div class="glossary-grid">
<div class="glossary-card reveal"><dt>LoRa</dt><dd>Long Range radio modulation technique enabling low-power, long-distance communication (1-15 km).</dd></div>
<div class="glossary-card reveal"><dt>Meshtastic</dt><dd>Open source LoRa mesh firmware for off-grid communication on ESP32 devices.</dd></div>
<div class="glossary-card reveal"><dt>Flooding</dt><dd>Broadcasting packets to all nodes in the network — simple but wasteful at scale.</dd></div>
<div class="glossary-card reveal"><dt>Geohash</dt><dd>Hierarchical geographic coordinate encoding that maps locations to short alphanumeric strings.</dd></div>
<div class="glossary-card reveal"><dt>OSPF</dt><dd>Open Shortest Path First — widely used internet routing protocol with area-based hierarchy.</dd></div>
<div class="glossary-card reveal"><dt>B.A.T.M.A.N.</dt><dd>Better Approach To Mobile Ad-hoc Networking — mesh protocol used by Freifunk community networks.</dd></div>
<div class="glossary-card reveal"><dt>ECMP</dt><dd>Equal-Cost Multi-Path routing — distributing traffic across multiple routes of similar quality.</dd></div>
<div class="glossary-card reveal"><dt>OGM</dt><dd>Originator Message — periodic beacon in B.A.T.M.A.N. used to discover and rank neighbors.</dd></div>
<div class="glossary-card reveal"><dt>NHS</dt><dd>Network Health Score — our composite metric combining connectivity, load, and battery state.</dd></div>
<div class="glossary-card reveal"><dt>QoS</dt><dd>Quality of Service — traffic prioritization ensuring critical messages (SOS) always get through.</dd></div>
<div class="glossary-card reveal"><dt>MQTT</dt><dd>Message queue protocol used as an internet bridge between geographically separated mesh clusters.</dd></div>
<div class="glossary-card reveal"><dt>DTN</dt><dd>Delay Tolerant Networking — store-and-forward approach for networks with intermittent connectivity.</dd></div>
<div class="glossary-card reveal"><dt>Distance-Vector</dt><dd>Routing protocol where nodes learn routes from neighbor advertisements (OGMs) rather than computing full graph traversals. Used in RIP, B.A.T.M.A.N., and System V6.</dd></div>
<div class="glossary-card reveal"><dt>RSSI</dt><dd>Received Signal Strength Indicator — measures how strongly a radio signal is received (in dBm).</dd></div>
<div class="glossary-card reveal"><dt>SNR</dt><dd>Signal-to-Noise Ratio — measures signal quality relative to background noise (in dB).</dd></div>
<div class="glossary-card reveal"><dt>Half-Duplex</dt><dd>A radio that cannot transmit and receive at the same time. All LoRa radios are half-duplex — a node hearing a transmission is blocked from sending until the packet ends.</dd></div>
<div class="glossary-card reveal"><dt>Backpressure</dt><dd>Congestion signal: when a node's queue fills up, routes through it get penalized. Traffic naturally shifts to less-loaded paths — like water flowing around rocks.</dd></div>
<div class="glossary-card reveal"><dt>Border Node</dt><dd>A System V6 node that has neighbors in a different geographic cluster. Border nodes are the bridges for inter-cluster routing — each cluster pair has 2 border links.</dd></div>
<div class="glossary-card reveal"><dt>Capture Effect</dt><dd>In LoRa, if two packets collide but one is ≥6dB stronger, the stronger signal "captures" the receiver and is decoded successfully. The weaker packet is lost.</dd></div>
</div>
</section>
<!-- CONCLUSION TEASER -->
<section id="conclusion">
<div class="section-tag reveal">13 — Conclusion</div>
<h2 class="section-title reveal">The Path Forward</h2>
<p class="section-desc reveal">Half-duplex radio physics collapse managed flooding to <strong>0–60% delivery</strong> in ALL scenarios — not just Bay Area. At 100 nodes, only 27% of messages arrive. At 1000 nodes, 0%. System V6 breaks through these barriers with directed routing at ~1 TX per hop, surviving both the hop limit wall and the half-duplex collision cascade. Across 26 scenarios (all with half-duplex and collisions enabled), System V6 is the only approach that maintains high delivery — 100% at up to 200 nodes, 46% at 1000 nodes where flooding delivers nothing. Very large sparse networks remain challenging for any protocol. The protocol is fully specified, a working ESP32 firmware prototype exists for three board types, and the complete source code is open under MIT license.</p>
<div class="concl-results-grid reveal" style="margin-bottom:2.5rem">
<div class="concl-result">
<div class="concl-result-value" style="color:var(--green)">100%</div>
<div class="concl-result-label">Delivery ≤200n</div>
</div>
<div class="concl-result">
<div class="concl-result-value" style="color:var(--teal)">99.9%</div>
<div class="concl-result-label">BW Saved (best)</div>
</div>
<div class="concl-result">
<div class="concl-result-value" style="color:var(--cyan)">~1</div>
<div class="concl-result-label">TX per Hop</div>
</div>
<div class="concl-result">
<div class="concl-result-value" style="color:var(--purple)">26</div>
<div class="concl-result-label">Scenarios</div>
</div>
</div>
<div class="concl-cta reveal">
<h3>Read the Full Executive Summary</h3>
<p>Complete analysis with problem statement, all five approaches evaluated, mathematical scoring, resilience design, QoS architecture, and the project roadmap.</p>
<div class="concl-cta-links">
<a href="how-it-works.html" class="concl-cta-item" style="text-decoration:none">🔧 How It Works (Technical Deep Dive)</a>
<a href="simulator.html" class="concl-cta-item" style="text-decoration:none">🎮 Live Simulator (Bay Area & more)</a>
<a href="docs/bay-area-feedback-response.md" class="concl-cta-item" style="text-decoration:none">🌊 Bay Area Mesh Q&A</a>
<a href="summary.html" class="concl-cta-item" style="text-decoration:none">📄 Executive Summary</a>
<a href="https://github.com/ClemensSimon/MeshRoute" class="concl-cta-item" style="text-decoration:none" target="_blank" rel="noopener">💻 GitHub</a>
<a href="https://discord.com/invite/meshtastic" class="concl-cta-item" style="text-decoration:none" target="_blank" rel="noopener">📡 Meshtastic Discord</a>
</div>
</div>
</section>
<footer>
<p>MeshRoute — Algorithm Research for Meshtastic / LoRa Mesh Networks</p>
<p style="margin-top:0.5rem">By <strong style="color:var(--cyan)">Clemens Simon</strong> — 2026</p>
<p style="margin-top:0.3rem;font-size:0.75rem">Built with pure HTML, CSS & Canvas. No dependencies. · MIT License</p>
</footer>
<!-- JS Modules (order matters: utils first, then engines, then simulations, then UI) -->
<script src="js/utils.js"></script>
<script src="js/hero.js"></script>
<script src="js/mesh-sim.js"></script>
<script src="js/algo-sims.js"></script>
<script src="js/map-sim.js"></script>
<script src="js/scenario-sims.js"></script>
<script src="js/formation.js"></script>
<script src="js/resilience.js"></script>
<script src="js/sim-results.js"></script>
<script src="js/ui.js"></script>
</body>
</html>