# rss_item

guid: https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/
title: Ryzen 7 Mini-PC makes a power-efficient VM host
url: https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<p>When I saw the first reviews of the <a href="https://www.asrock.com/nettop/AMD/DeskMini%20X600%20Series/index.asp">ASRock DeskMini X600
barebone</a>,
I was immediately interested in building a home-lab hypervisor (VM host) with
it. Apparently, the DeskMini X600 uses less than 10W of power but supports
latest-generation AMD CPUs like the Ryzen 7 8700G!</p>
<p>Sounds like the perfect base for a power-efficient, always-on VM host that still
provides enough compute power (and fast disks!) to be competitive with
commercial VM offerings. In this article, I’ll show how I built and set up my
DIY self-hosting VM host.</p>















<a href="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/240630-server-featured.jpg"><img
  srcset="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/240630-server-featured_hu3cb7c72c5372ea18e945c976b24c8b83_4997169_1200x0_resize_q75_box.jpg 2x,https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/240630-server-featured_hu3cb7c72c5372ea18e945c976b24c8b83_4997169_1800x0_resize_q75_box.jpg 3x"
  src="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/240630-server-featured_hu3cb7c72c5372ea18e945c976b24c8b83_4997169_600x0_resize_q75_box.jpg"
  alt="ASRock DeskMini X600" title="ASRock DeskMini X600"
  width="600"
  height="401"
  style="

border: 1px solid #000;

"
  
  loading="lazy"></a>



<h2 id="component-list">Component List</h2>
<p>The term “barebone” means that the machine comes without CPU, RAM and disk. You
only get a case with a mainboard and power supply, the rest is up to you. I
chose the following parts:</p>
<table>
<thead>
<tr>
<th>Price</th>
<th>Type</th>
<th>Article</th>
</tr>
</thead>
<tbody>
<tr>
<td>215 EUR</td>
<td>barebone</td>
<td><a href="https://shop.jzelectronic.de/product_info.php?info=p75250_asrock-deskmini-x600.html">ASRock DeskMini X600</a></td>
</tr>
<tr>
<td>293 CHF</td>
<td>CPU</td>
<td><a href="https://www.digitec.ch/de/s1/product/amd-ryzen-7-8700g-am5-420-ghz-8-core-prozessor-42390585?supplier=406802">AMD Ryzen 7 8700G (AM5, 4.20 GHz, 8 Core)</a></td>
</tr>
<tr>
<td>48 CHF</td>
<td>CPU fan</td>
<td><a href="https://www.digitec.ch/de/s1/product/noctua-nh-l9a-am5-37-mm-cpu-kuehler-24147242?supplier=406802">Noctua NH-L9a-AM5 (37 mm)</a></td>
</tr>
<tr>
<td>195 CHF</td>
<td>RAM</td>
<td><a href="https://www.digitec.ch/de/s1/product/kingston-fury-impact-2-x-32gb-5600-mhz-ddr5-ram-so-dimm-ram-23704483?supplier=406802">Kingston FURY Impact (2 x 32GB, DDR5-5600 SO-DIMM)</a></td>
</tr>
<tr>
<td>218 CHF</td>
<td>SSD</td>
<td>2 x <a href="https://www.digitec.ch/de/s1/product/samsung-980-pro-1000-gb-m2-2280-ssd-13823466?supplier=406802">Samsung 980 Pro (1000 GB, M.2 2280)</a> (for RAID-1)</td>
</tr>
</tbody>
</table>
<p>Total cost: 969 CHF</p>
<p>The CPU fan is not strictly required (the DeskMini X600 already comes with a
fan), but I wanted the best cooling performance at lowest noise levels, so
Noctua it is.</p>
<p><del>I read that the machine should support ECC RAM, too</del>. <strong>Update:</strong> The <a href="https://www.tomshardware.com/pc-components/cpus/amd-confirms-ryzen-8000g-apus-dont-support-ecc-ram-despite-initial-claims">Ryzen
8700G does not support
ECC-RAM</a>
after all. Only the Ryzen 7 <strong>PRO</strong> 8700G supports ECC-RAM.</p>















<a href="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/IMG_3871.jpg"><img
  srcset="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/IMG_3871_hu59fa65490ce2e48b2c5b284fe97e0775_2062424_1200x0_resize_q75_box.jpg 2x,https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/IMG_3871_hu59fa65490ce2e48b2c5b284fe97e0775_2062424_1800x0_resize_q75_box.jpg 3x"
  src="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/IMG_3871_hu59fa65490ce2e48b2c5b284fe97e0775_2062424_600x0_resize_q75_box.jpg"
  alt="components" title="components"
  width="600"
  height="631"
  style="

border: 1px solid #000;

"
  
  loading="lazy"></a>



<p>It took me about an hour to assemble the parts. Note that the M.2 SSD screws
might seem a little hard to screw in, but don’t be deterred by that. When first
powering on the system, be patient as the memory training will take a minute or so,
during which the screen will stay black.</p>
<h2 id="uefi-setup">UEFI Setup</h2>
<p>The UEFI on the DeskMini X600 comes with reasonable defaults.</p>
<p>The CPU fan setting alreadys defaults to “Silent Mode”, for example.</p>
<p>I changed the following option, which is typical for server usage:</p>
<ul>
<li>Advanced → ACPI Configuration → Restore on AC/Power Loss: Power On</li>
</ul>
<p>And I disabled the onboard devices I know I won’t need, just in case it saves power:</p>
<ul>
<li>Advanced → Onboard Devices Configuration → Onboard HD Audio: Disabled</li>
<li>SATA3 Controller: Disabled</li>
</ul>
<h2 id="operating-system-setup">Operating System Setup</h2>
<p>I want to run this machine as a VM hypervisor. The easiest way that I know to set up such a hypervisor is to install Proxmox, an open
source virtualization appliance based on Debian.</p>
<p>I booted the machine with the Proxmox installer copied to a USB memory stick,
then selected ZFS in a RAID-1 configuration. The setup worked smoothly and was
done in a few minutes.</p>
<p>Then, I set up Tailscale <a href="https://tailscale.com/kb/1133/proxmox">as recommended</a>
and used <code>tailscale serve</code> so that I can access the Proxmox web interface on its
Tailscale hostname via HTTPS, instead of having to deal with certificates and
custom ports:</p>
<pre tabindex="0"><code>pve# curl -fsSL https://tailscale.com/install.sh | sh
pve# tailscale up
[…]
  follow instructions and disable key expiration
[…]
pve# tailscale serve --bg https+insecure://localhost:8006
</code></pre><p>(Of course I’ll also install Tailscale on each VM running on the host.)</p>
<p>Now I can log into the Proxmox web interface from anywhere without certificate
warnings:</p>















<a href="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-30-proxmox.jpg"><img
  srcset="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-30-proxmox_hu72d4f4d0189dc6f0891d857b6c038b39_1406117_1200x0_resize_q75_box.jpg 2x,https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-30-proxmox_hu72d4f4d0189dc6f0891d857b6c038b39_1406117_1800x0_resize_q75_box.jpg 3x"
  src="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-30-proxmox_hu72d4f4d0189dc6f0891d857b6c038b39_1406117_600x0_resize_q75_box.jpg"
  alt="proxmox web interface" title="proxmox web interface"
  width="600"
  height="418"
  style="

border: 1px solid #000;

"
  
  loading="lazy"></a>



<p>In this screenshot, I have already created 2 VMs (“batch” and “web”) using the
“Create VM” button at the top right. Proxmox allows controlling the installer
via its “Console” tab and once set up, the VM shows up in the same network that
the hypervisor is connected to with a MAC address from the “Proxmox Server
Solutions GmbH” range. That’s pretty much all there is to it.</p>
<p>I don’t have enough nodes for advanced features like clustering, but I might
investigate whether I want to set up backups on the Proxmox layer or keep doing
them on the OS layer.</p>
<h3 id="fan-speed-monitoring">Fan speed monitoring</h3>
<p>Sven Geggus shared how to make the fan speed sensors work in current versions of
Debian:</p>
<pre tabindex="0"><code>pve# echo &#34;options nct6683 force=1&#34; &gt;&gt; /etc/modprobe.d/sensors.conf
pve# echo nct6683 &gt;&gt; /etc/modules-load.d/sensors.conf
pve# modprobe nct6683
pve# systemctl restart prometheus-node-exporter
</code></pre><h2 id="power-usage">Power Usage</h2>
<p>The power usage values I measure are indeed excellent: The DeskMini X600 with
Ryzen 7 8700G consumes less than 10W (idle)! When the machine has something to
do, it spikes up to 50W:</p>















<a href="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-24-energy-usage.jpg"><img
  srcset="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-24-energy-usage_hu6ff618f9e9023ea7df34e8fd6d4f3691_213887_1200x0_resize_q75_box.jpg 2x,https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-24-energy-usage_hu6ff618f9e9023ea7df34e8fd6d4f3691_213887_1800x0_resize_q75_box.jpg 3x"
  src="https://michael.stapelberg.ch/posts/2024-07-02-ryzen-7-mini-pc-low-power-proxmox-hypervisor/2024-06-24-energy-usage_hu6ff618f9e9023ea7df34e8fd6d4f3691_213887_600x0_resize_q75_box.jpg"
  alt="Grafana dashboard showing power usage" title="Grafana dashboard showing power usage"
  width="600"
  height="257"
  style="

border: 1px solid #000;

"
  
  loading="lazy"></a>



<h2 id="noise">Noise</h2>
<p>ASRock explicitly lists the Noctua NH-L9a-AM5 as compatible with the DeskMini
X600, which was one of the factors that made me select this barebone. Installing
the fan was easy.</p>
<p>Fan noise is very low, as expected with Noctua. I can’t hear the device even
when it is standing in front of me on my desk. Of course, under heavy load, the
fan will be audible. This is an issue with all small form-factor PCs, as they
just don’t have enough case space to swallow more noise.</p>
<p>Aside from the fan noise, if you hold your ear directly next to the X600, you
can hear the usual electrical component noise (not coil whine per se, but that
sort of thing).</p>
<p>I recommend positioning this device under a desk, or on a shelf, or
similar.</p>
<h2 id="performance-comparison">Performance comparison</h2>
<p>You can find synthetic benchmark results for the Ryzen 8700G elsewhere, so as
usual, I will write about the specific angle I care about: How fast can this
machine handle Go workloads?</p>
<h3 id="compiling-go-1224">Compiling Go 1.22.4</h3>
<p>On the Ryzen 8700G, we can compile Go 1.22.4 in a little under 40 seconds:</p>
<pre tabindex="0"><code>% time ./make.bash
[…]
./make.bash  208,55s user 36,96s system 631% cpu 38,896 total
</code></pre><p>For comparison, <a href="/posts/2022-01-15-high-end-linux-pc/">my 2022 high-end Linux PC with Core
i9-12900K</a> is only a few seconds faster:</p>
<pre tabindex="0"><code>% time ./make.bash
[…]
./make.bash  207,33s user 29,55s system 685% cpu 34,550 total
</code></pre><h3 id="go-http-and-json-benchmarks">Go HTTP and JSON benchmarks</h3>
<p>I also ran the HTTP and JSON benchmarks from Go’s <a href="https://github.com/golang/benchmarks">x/benchmarks
repository</a>.</p>
<p>Compared to the Virtual Server I’m currently renting, the Ryzen 8700G is more
than twice as fast:</p>
<pre tabindex="0"><code>% benchstat rentedvirtual ryzen8700g 
name    old time/op                  new time/op                  delta
HTTP-2  28.5µs ± 2%                  10.2µs ± 1%  -64.17%  (p=0.008 n=5+5)
JSON-2  24.1ms ±29%                   9.4ms ± 1%  -61.06%  (p=0.008 n=5+5)
</code></pre><p>Of course, the Intel i9 12900K is still a bit faster — how much depends on the
specific workload:</p>
<pre tabindex="0"><code>% benchstat ryzen8700g i9_12900k 
name    old time/op                  new time/op                  delta
HTTP-2  10.2µs ± 1%                   7.6µs ± 1%  -25.13%  (p=0.008 n=5+5)
JSON-2  9.40ms ± 1%                  9.23ms ± 1%   -1.82%  (p=0.008 n=5+5)
</code></pre><h2 id="conclusion">Conclusion</h2>
<p>What a delightful little Mini-PC! It’s modern enough to house the current
generation of CPUs, compact enough to fit in well anywhere, yet just large
enough to fit a Noctua CPU cooler for super-quiet operation. The low power draw
makes it acceptable to run this machine 24/7.</p>
<p>Paired with 64 GB of RAM and large, fast NVMe disks, this machine packs a punch
and will easily power your home automation, home lab, hobby project, small office server, etc.</p>
<p>If a Raspberry Pi isn’t enough for your needs, check out the DeskMini X600, or
perhaps its larger variant, the <a href="https://www.asrock.com/nettop/AMD/DeskMeet%20X600%20Series/index.asp">DeskMeet
X600</a>
which is largely identical, but comes with a PCIe slot.</p>
<p>If this one doesn’t fit your needs, keep looking: there are many more mini PCs
on the market. Check out <a href="https://www.servethehome.com/introducing-project-tinyminimicro-home-lab-revolution/">ServeTheHome’s “Project
TinyMiniMicro”</a>
for a lot more reviews.</p>
<p><strong>Update:</strong> Apparently ASRock is <a href="https://www.golem.de/news/asrock-x600tm-itx-sehr-flaches-am5-mainboard-mit-externer-stromversorgung-2407-187469.html">releasing their X600
mainboard</a>
as a standalone product, too, if you like the electronics but not the form
factor.</p>


guid: https://michael.stapelberg.ch/posts/2024-09-18-a-signal-run-a-day-keeps-the-un-link-away/
title: A Signal run a day keeps the un-link away
url: https://michael.stapelberg.ch/posts/2024-09-18-a-signal-run-a-day-keeps-the-un-link-away/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<p>I have a couple of people who are best reachable on the <a href="https://en.wikipedia.org/wiki/Signal_(software)">Signal messaging
app</a>, but not that many. This
exposes me to an awkward edge case of Signal’s design decisions: Whenever I get
a message (on my phone), I want to reply to it (on my laptop) only to discover
that Signal has un-linked my laptop because of inactivity and won’t sync the
message history from my phone to my laptop, making it impossible to quote-reply
to messages.</p>
<p>After complaining about this on Social Media for the n-th time, I figured I’d
write a quick program to run Signal once a day, so that it won’t un-link my
devices because of too long a period of inactivity. (Of course, the easiest
solution would be to just run Signal in the background all the time. But I don’t
use Signal often enough to justify letting it drain my battery and mobile data.)</p>
<p>In this article, I want to share the program in case it’s useful to anyone else,
and also explain how to install it on a Mac, as this kind of “do a task once a
day” automation is a useful pattern.</p>
<p><img src="2024-09-18-signal-screenshot-featured.jpg" alt=""></p>
<h2 id="high-level-sketch">High-level sketch</h2>
<ol>
<li>Run Signal for, say, 5 minutes.</li>
<li>Ensure at-most-once semantics regardless of the task scheduler. For example,
if I wanted to start this program from an <code>@reboot</code> hook and restart my
computer a few times, I don’t want the program to do anything after the first
run of the day. (Similarly, an on-online hook of NetworkManager or similar
software might fire once per network interface, or something like that.)</li>
<li>Depending on the specifics of the activation mechanism, the computer might be
online or not. The program should wait for a little while, say, 10 minutes,
until internet connectivity was established.</li>
<li>I would like to log the program’s output (and Signal’s output) for debugging.</li>
</ol>
<h2 id="checking-connectivity">Checking connectivity</h2>
<p>The easiest option is to just… not do a connectivity check at all, and hope for
the best. This would probably work well enough in practice, but I would like the
debug logs to have a high signal-to-noise ratio: If I have to debug why Signal
was unlinked despite my automation attempts, I don’t want to comb through tons
of spurious log messages that were a result from being offline. So, I want to
check that I’m online before even starting Signal.</p>
<p>The most thorough option would be to somehow ask Signal programmatically whether
it can connect to its servers and then wait until it can. I don’t think Signal
has such an interface, so we’ll chose a middle-ground solution and work with a
stand-in.</p>
<p>Using HTTP for connectivity checks is an easy way in today’s world. We just need
a target website that doesn’t go offline unless I want it to. So let’s just use
this website! Go’s <code>net/http</code> package that is included in Go’s standard library
makes this super easy:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">checkConnectivity</span>() <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	_, err <span style="color:#666">:=</span> http.<span style="color:#06287e">Get</span>(<span style="color:#4070a0">&#34;https://michael.stapelberg.ch/&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Now we just need to loop around this single connectivity check:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">waitForConnectivity</span>(timeout time.Duration) <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">const</span> freq = <span style="color:#40a070">1</span> <span style="color:#666">*</span> time.Second
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">for</span> start <span style="color:#666">:=</span> time.<span style="color:#06287e">Now</span>(); time.<span style="color:#06287e">Since</span>(start) &lt; timeout; time.<span style="color:#06287e">Sleep</span>(freq) {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#06287e">checkConnectivity</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>			log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;connectivity check failed: %v&#34;</span>, err)
</span></span><span style="display:flex;"><span>			<span style="color:#007020;font-weight:bold">continue</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> <span style="color:#007020;font-weight:bold">nil</span> <span style="color:#60a0b0;font-style:italic">// connectivity check succeeded
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> fmt.<span style="color:#06287e">Errorf</span>(<span style="color:#4070a0">&#34;no connectivity established within %v&#34;</span>, timeout)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>We could improve this code to be more generally applicable by adding
<a href="https://en.wikipedia.org/wiki/Exponential_backoff">Exponential Backoff</a>, but
for this particular connectivity check, we should be fine even without
Exponential Backoff.</p>
<h2 id="ensuring-at-most-once-semantics">Ensuring at-most-once semantics</h2>
<p>An easy way to implement at-most-once semantics is to delegate to the file
system: we can specify the <code>O_EXCL</code> flag when creating our program’s log file to
make the first creation attempt proceed, but any further creation attempt fail
because the file already exists. We’ll then redirect the standard library’s
<code>log</code> package output to the log file:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span>logFn <span style="color:#666">:=</span> filepath.<span style="color:#06287e">Join</span>(home, <span style="color:#4070a0">&#34;signal-keepalive&#34;</span>, <span style="color:#4070a0">&#34;_logs&#34;</span>, time.<span style="color:#06287e">Now</span>().<span style="color:#06287e">Format</span>(<span style="color:#4070a0">&#34;2006-01-02&#34;</span>)<span style="color:#666">+</span><span style="color:#4070a0">&#34;.txt&#34;</span>)
</span></span><span style="display:flex;"><span>f, err <span style="color:#666">:=</span> os.<span style="color:#06287e">OpenFile</span>(logFn, os.O_RDWR|os.O_CREATE|os.O_EXCL, <span style="color:#40a070">0666</span>)
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> os.<span style="color:#06287e">IsExist</span>(err) {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> <span style="color:#007020;font-weight:bold">nil</span> <span style="color:#60a0b0;font-style:italic">// nothing to do, already ran today
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic">// Intentionally not closing this file so that even the log.Fatal()
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic">// call in the calling function will end up in the log file.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>
</span></span><span style="display:flex;"><span>log.<span style="color:#06287e">SetOutput</span>(f) <span style="color:#60a0b0;font-style:italic">// redirect standard library logging into this file
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;signal-keepalive, waiting for internet connectivity&#34;</span>)
</span></span></code></pre></div><p>Not closing the file might seem weird at first, but remember that this is a
short-lived program and the operating system closes all file handles of a
process when it exits.</p>
<h2 id="full-program-code">Full program code</h2>
<p>For your convenience, here is the full program code. It contains a bunch of file
system paths that you might want or need to adjust.</p>
<details>
<summary>Click to expand: <code>keepalive.go</code></summary>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">package</span> main
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;log&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;net/http&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;os&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;os/exec&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;path/filepath&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;time&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">checkConnectivity</span>() <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	_, err <span style="color:#666">:=</span> http.<span style="color:#06287e">Get</span>(<span style="color:#4070a0">&#34;https://michael.stapelberg.ch/&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">waitForConnectivity</span>(timeout time.Duration) <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">for</span> start <span style="color:#666">:=</span> time.<span style="color:#06287e">Now</span>(); time.<span style="color:#06287e">Since</span>(start) &lt; timeout; time.<span style="color:#06287e">Sleep</span>(<span style="color:#40a070">1</span> <span style="color:#666">*</span> time.Second) {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#06287e">checkConnectivity</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>			log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;connectivity check failed: %v&#34;</span>, err)
</span></span><span style="display:flex;"><span>			<span style="color:#007020;font-weight:bold">continue</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> <span style="color:#007020;font-weight:bold">nil</span> <span style="color:#60a0b0;font-style:italic">// connectivity check succeeded
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> fmt.<span style="color:#06287e">Errorf</span>(<span style="color:#4070a0">&#34;no connectivity established within %v&#34;</span>, timeout)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">keepalive</span>() <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Limit to one attempt per day by exclusively creating a logfile.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	home <span style="color:#666">:=</span> os.<span style="color:#06287e">Getenv</span>(<span style="color:#4070a0">&#34;HOME&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> home <span style="color:#666">==</span> <span style="color:#4070a0">&#34;&#34;</span> {
</span></span><span style="display:flex;"><span>		home = <span style="color:#4070a0">&#34;/Users/michael&#34;</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	logFn <span style="color:#666">:=</span> filepath.<span style="color:#06287e">Join</span>(home, <span style="color:#4070a0">&#34;signal-keepalive&#34;</span>, <span style="color:#4070a0">&#34;_logs&#34;</span>, time.<span style="color:#06287e">Now</span>().<span style="color:#06287e">Format</span>(<span style="color:#4070a0">&#34;2006-01-02&#34;</span>)<span style="color:#666">+</span><span style="color:#4070a0">&#34;.txt&#34;</span>)
</span></span><span style="display:flex;"><span>	f, err <span style="color:#666">:=</span> os.<span style="color:#06287e">OpenFile</span>(logFn, os.O_RDWR|os.O_CREATE|os.O_EXCL, <span style="color:#40a070">0666</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">if</span> os.<span style="color:#06287e">IsExist</span>(err) {
</span></span><span style="display:flex;"><span>			<span style="color:#007020;font-weight:bold">return</span> <span style="color:#007020;font-weight:bold">nil</span> <span style="color:#60a0b0;font-style:italic">// nothing to do, already ran today
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Intentionally not closing this file so that even the log.Fatal()
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// call in the calling function will end up in the log file.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">SetOutput</span>(f) <span style="color:#60a0b0;font-style:italic">// redirect standard library logging into this file
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;signal-keepalive, waiting for internet connectivity&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Wait for network connectivity
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#06287e">waitForConnectivity</span>(<span style="color:#40a070">10</span> <span style="color:#666">*</span> time.Minute); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Start signal
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;connectivity verified, starting signal&#34;</span>)
</span></span><span style="display:flex;"><span>	signal <span style="color:#666">:=</span> exec.<span style="color:#06287e">Command</span>(<span style="color:#4070a0">&#34;/Applications/Signal.app/Contents/MacOS/Signal&#34;</span>, <span style="color:#4070a0">&#34;--start-in-tray&#34;</span>)
</span></span><span style="display:flex;"><span>	signal.Stdout = f
</span></span><span style="display:flex;"><span>	signal.Stderr = f
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> signal.<span style="color:#06287e">Start</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Wait for some time to give Signal a chance to synchronize messages.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#007020;font-weight:bold">const</span> signalWaitTime = <span style="color:#40a070">5</span> <span style="color:#666">*</span> time.Minute
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;giving signal %v to sync messages&#34;</span>, signalWaitTime)
</span></span><span style="display:flex;"><span>	time.<span style="color:#06287e">Sleep</span>(signalWaitTime)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Stop signal
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;killing signal&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> signal.Process.<span style="color:#06287e">Kill</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;waiting for signal&#34;</span>)
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;signal returned: %v&#34;</span>, signal.<span style="color:#06287e">Wait</span>())
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">Printf</span>(<span style="color:#4070a0">&#34;all done&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> f.<span style="color:#06287e">Sync</span>()
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#06287e">keepalive</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		log.<span style="color:#06287e">Fatal</span>(err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></details>
<p>(Use <code>go build keepalive.go</code> to compile if you’re unfamiliar with <a href="https://go.dev">Go</a>.)</p>
<h2 id="macos-installation-launchd">macOS installation: launchd</h2>
<p>The corresponding piece of infrastructure to
<a href="https://en.wikipedia.org/wiki/Systemd">systemd</a> on Linux is called
<a href="https://en.wikipedia.org/wiki/Launchd">launchd</a> on macOS. Aside from managing
daemon processes, launchd also supports time-triggered program execution,
specifically via the <code>StartCalendarInterval</code> configuration option.</p>
<p>I followed <a href="https://alvinalexander.com/mac-os-x/launchd-plist-examples-startinterval-startcalendarinterval/">Alvin Alexander’s blog post about launchd StartCalendarInterval
examples</a>
and decided to configure my program to run at 08:03 each day:</p>
<details>
<summary>
Click to expand: <code>net.zekjur.signalkeepalive.plist</code>
</summary>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#007020">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#007020">&lt;!DOCTYPE plist PUBLIC &#34;-//Apple Computer//DTD PLIST 1.0//EN&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#007020">&#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#062873;font-weight:bold">&lt;plist</span> <span style="color:#4070a0">version=</span><span style="color:#4070a0">&#34;1.0&#34;</span><span style="color:#062873;font-weight:bold">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#062873;font-weight:bold">&lt;dict&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;key&gt;</span>StartCalendarInterval<span style="color:#062873;font-weight:bold">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;dict&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#062873;font-weight:bold">&lt;key&gt;</span>Hour<span style="color:#062873;font-weight:bold">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#062873;font-weight:bold">&lt;integer&gt;</span>8<span style="color:#062873;font-weight:bold">&lt;/integer&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#062873;font-weight:bold">&lt;key&gt;</span>Minute<span style="color:#062873;font-weight:bold">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#062873;font-weight:bold">&lt;integer&gt;</span>3<span style="color:#062873;font-weight:bold">&lt;/integer&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;/dict&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;key&gt;</span>Label<span style="color:#062873;font-weight:bold">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;string&gt;</span>net.zekjur.signalkeepalive<span style="color:#062873;font-weight:bold">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;key&gt;</span>Program<span style="color:#062873;font-weight:bold">&lt;/key&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#062873;font-weight:bold">&lt;string&gt;</span>/Users/michael/signal-keepalive/signalkeepalive<span style="color:#062873;font-weight:bold">&lt;/string&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#062873;font-weight:bold">&lt;/dict&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#062873;font-weight:bold">&lt;/plist&gt;</span>
</span></span></code></pre></div></details>
<p>What happens when my computer isn’t running at 08:03, for example because the
lid is closed? Apple documents the behavior in the <a href="https://keith.github.io/xcode-man-pages/launchd.plist.5.html"><code>launchd.plist(5)</code> man
page</a>:</p>
<blockquote>
<p><em>Unlike cron which skips job invocations when the computer is asleep, launchd
will start the job the next time the computer wakes up.</em></p>
</blockquote>
<p>To install and test this configuration:</p>
<ol>
<li>Copy the plist file to <code>~/Library/LaunchAgents</code></li>
<li>Run <code>launchctl load ~/Library/LaunchAgents/net.zekjur.signalkeepalive.plist</code></li>
<li>Run <code>launchctl start net.zekjur.signalkeepalive</code></li>
</ol>
<h2 id="in-practice">In practice</h2>
<p>It’s interesting to see this behavior in practice. Take note of the time stamps
in the following log. The computer was not running at 08:03. At 08:18, it woke
up to update background information (Apple calls this <a href="https://support.apple.com/en-az/guide/mac-help/mh40773/mac">“Power
Nap”</a>), and then it
suspended again (while Signal was running) until it woke up at 08:47 again:</p>
<pre tabindex="0"><code>2024/09/07 08:18:10 signal-keepalive, waiting for internet connectivity
2024/09/07 08:18:11 connectivity verified, starting signal
2024/09/07 08:18:11 giving signal 5m0s to sync messages
Set Windows Application User Model ID (AUMID) { AUMID: &#39;org.whispersystems.signal-desktop&#39; }
NODE_ENV production
NODE_CONFIG_DIR /Applications/Signal.app/Contents/Resources/app.asar/config
NODE_CONFIG {}
ALLOW_CONFIG_MUTATIONS undefined
HOSTNAME m1a.fritz.box
NODE_APP_INSTANCE undefined
SUPPRESS_NO_CONFIG_WARNING undefined
SIGNAL_ENABLE_HTTP undefined
userData: /Users/michael/Library/Application Support/Signal
config/get: Successfully read user config file
config/get: Successfully read ephemeral config file
2024/09/07 08:47:31 killing signal
2024/09/07 08:47:31 waiting for signal
2024/09/07 08:47:31 signal returned: signal: killed
2024/09/07 08:47:31 all done
</code></pre><h2 id="linux-installation-systemd">Linux installation: systemd</h2>
<p>With systemd, we need two units. First, a <code>signal-keepalive.service</code> unit to
declare which program should be run:</p>
<pre tabindex="0"><code>cat &gt; ~/.config/systemd/user/signal-keepalive.service &lt;&lt;&#39;EOT&#39;
[Unit]
Description=signal keepalive
After=network.target

[Service]
Type=oneshot
ExecStart=/home/michael/signal-keepalive/signalkeepalive

[Install]
WantedBy=default.target
EOT
</code></pre><p>And secondly, a <code>signal-keepalive.timer</code> unit which automatically starts the
<code>signal-keepalive.service</code> every day:</p>
<pre tabindex="0"><code>cat &gt; ~/.config/systemd/user/signal-keepalive.timer &lt;&lt;&#39;EOT&#39;
[Unit]
Description=signal keepalive

[Timer]
Persistent=true
OnCalendar=daily

[Install]
WantedBy=timers.target
EOT
</code></pre><p>The <code>Persistent=true</code> line is important so that the program will be run even
when the computer is asleep when the timer would have fired.</p>
<p>Let’s enable the timer:</p>
<pre tabindex="0"><code>systemctl --user enable --now signal-keepalive.timer
</code></pre><p>For an initial test run, we can start the .service directly:</p>
<pre tabindex="0"><code>systemctl --user restart signal-keepalive.service
</code></pre><h2 id="conclusion">Conclusion</h2>
<p>It’s silly that I need to go through so much trouble just because I don’t use
Signal enough.</p>
<p>I also don’t understand why Signal can’t just sync message history from my phone
to my computer when linking. WhatsApp and Telegram have no trouble doing it.</p>
<p>Either way, I thought this was a fun little refresher on automating periodic
jobs.</p>


guid: https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/
title: Debug Go core dumps with delve: export byte slices
url: https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<p>Not all bugs can easily be reproduced — sometimes, all you have is a core dump
from a crashing program, but no idea about the triggering conditions of the bug
yet.</p>
<p>When using Go, we can use <a href="https://github.com/go-delve/delve">the delve
debugger</a> for core dump debugging, but I had
trouble figuring out how to save byte slice contents (for example: the incoming
request causing the crash) from memory into a file for further analysis, so this
article walks you through how to do it.</p>
<h2 id="simple-example">Simple Example</h2>
<p>Let’s imagine the following scenario: You are working on a performance
optimization in <a href="https://pkg.go.dev/google.golang.org/protobuf">Go Protobuf</a> and
have accidentally badly broken the <a href="https://pkg.go.dev/google.golang.org/protobuf/proto#Marshal"><code>proto.Marshal</code>
function</a>. The
function is now returning an error, so let’s run one of the failing tests with
delve:</p>
<pre tabindex="0"><code>~/protobuf/proto master % dlv test
(dlv) b ExampleMarshal
(dlv) c
&gt; [Breakpoint 1] google.golang.org/protobuf/proto_test.ExampleMarshal() ./encode_test.go:293 (hits goroutine(1):1 total:1) (PC: 0x9d6c96)
(dlv) next 4
&gt; google.golang.org/protobuf/proto_test.ExampleMarshal() ./encode_test.go:297 (PC: 0xb54495)
   292: // [google.golang.org/protobuf/types/known/durationpb.New].
   293: func ExampleMarshal() {
   294: b, err := proto.Marshal(&amp;durationpb.Duration{
   295: Nanos: 125,
   296: })
=&gt; 297: if err != nil {
   298: panic(err)
   299: }
   300:
   301: fmt.Printf(&#34;125ns encoded into %d bytes of Protobuf wire format:\n% x\n&#34;, len(b), b)
   302:
</code></pre><p>Go Protobuf happens to return the already encoded bytes even when returning an
error, so we can inspect the <code>b</code> byte slice to see how far the encoding got
before the error happened:</p>
<pre tabindex="0"><code>(dlv) print b
[]uint8 len: 2, cap: 2, [16,125]
</code></pre><p>In this case, we can see that the entire (trivial) message was encoded, so our
error must happen at a later stage — this allows us to rule out a large chunk of
code in our search for the bug.</p>
<p>But what would we do if a longer part of the message was displayed and we wanted
to load it into a different tool for further analysis, e.g. the excellent
<a href="https://github.com/protocolbuffers/protoscope">protoscope</a>?</p>
<p>The low-tech approach is to print the contents and copy&amp;paste from the delve
output into an editor or similar. This stops working as soon as your data
contains non-printable characters.</p>
<p>We have multiple options to export the byte slice to a file:</p>
<ol>
<li>
<p>We could add <code>os.WriteFile(&quot;/tmp/b.raw&quot;, b, 0644)</code> to the source code and
re-run the test. This is definitely the simplest option, as it works with or
without a debugger.</p>
</li>
<li>
<p>As long as delve is connected to a running program, we can use delve’s call
command to just execute the same code without having to add it to our source:</p>
<pre tabindex="0"><code>(dlv) call os.WriteFile(&#34;/tmp/b.raw&#34;, b, 0644)
(dlv)
</code></pre></li>
</ol>
<p>Notably, both options only work when you can debug interactively. For the first
option, you need to be able to change the source. The second option requires
that delve is attached to a running process that you can afford to pause and
interactively control.</p>
<p>These are trivial requirements when running a unit tests on your local machine,
but get much harder when debugging an RPC service that crashes with specific
requests, as you need to only run your changed debugging code for the
troublesome requests, skipping the unproblematic requests that should still be
handled normally.</p>
<h2 id="core-dump-debugging-with-go">Core dump debugging with Go</h2>
<p>So let’s switch example: we are no longer working on Go Protobuf. Instead, we
now need to debug an RPC service where certain requests crash the service. We’ll
use core dump debugging!</p>















<a href="https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/core-memory-featured.jpg"><img
  srcset="https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/core-memory-featured_huc92a382266793767583fa56b2a20c9d0_1575273_1200x0_resize_q75_box.jpg 2x,https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/core-memory-featured_huc92a382266793767583fa56b2a20c9d0_1575273_1800x0_resize_q75_box.jpg 3x"
  src="https://michael.stapelberg.ch/posts/2024-10-22-debug-go-core-dumps-delve-export-bytes/core-memory-featured_huc92a382266793767583fa56b2a20c9d0_1575273_600x0_resize_q75_box.jpg"
  alt="Core memory" title="Core memory"
  width="600"
  height="516"
  style="

border: 1px solid #000;

"
  
  loading="lazy"></a>



<p>In case you’re wondering: The name “<a href="https://en.wikipedia.org/wiki/Core_dump">core
dump</a>” comes from <a href="https://en.wikipedia.org/wiki/Magnetic-core_memory">magnetic-core
memory</a>. These days we
should probably say “memory dump” instead. The picture above shows an exhibit
from the <a href="https://mitmuseum.mit.edu/">MIT Museum</a> (<em>Core Memory Unit, Bank C
(from Project Whirlwind, 1953-1959))</em>, a core memory unit with 4 KB of capacity.</p>
<p>To make Go write a core dump when panicing, run your program with the
environment variable <code>GOTRACEBACK=crash</code> set (all possible values are documented
<a href="https://pkg.go.dev/runtime">in the <code>runtime</code> package</a>).</p>
<p>You also need to ensure your system is set up to collect core dumps, as they are
typically discarded by default:</p>
<ul>
<li>On Linux, the easiest way is to install <a href="https://manpages.debian.org/systemd-coredump.8"><code>systemd-coredump(8)</code></a>
, after which core dumps will automatically be collected. You
can use <a href="https://manpages.debian.org/coredumpctl.1"><code>coredumpctl(1)</code></a>
 to list and work with them.</li>
<li>On macOS, you can enable core dump collection, but <a href="https://github.com/go-delve/delve/issues/2026">delve cannot open macOS
core dumps</a>. Luckily, macOS is
rarely used for production servers.</li>
<li>I don’t know about Windows and other systems.</li>
</ul>
<p>You can find more details and options in the <a href="https://go.dev/wiki/CoreDumpDebugging">CoreDumpDebugging page of the Go
wiki</a>. For this article, we will stick to
the <code>coredumpctl</code> route:</p>
<p>We’ll use the <a href="https://grpc.io/docs/languages/go/quickstart/">gRPC Go Quick start
example</a>, a greeter client/server
program, and add a <code>panic()</code> call to the server <code>SayHello</code> handler:</p>
<pre tabindex="0"><code>% cd greeter_server
% go build -gcflags=all=&#34;-N -l&#34;  # disable optimizations
% GOTRACEBACK=crash ./greeter_server
2024/10/19 21:48:01 server listening at [::]:50051
2024/10/19 21:48:03 Received: world
panic: oh no!

goroutine 5 gp=0xc000007c00 m=5 mp=0xc000100008 [running]:
panic({0x83ca60?, 0x9a3710?})
	/home/michael/sdk/go1.23.0/src/runtime/panic.go:804 +0x168 fp=0xc000169850 sp=0xc0001697a0 pc=0x46fe88
main.(*server).SayHello(0xcbb840?, {0x877200?, 0xc000094900?}, 0x4a6f25?)
	/home/michael/go/src/github.com/grpc/grpc-go/examples/helloworld/greeter_server/main.go:45 +0xbf fp=0xc0001698c0 sp=0xc000169850 pc=0x8037ff
[…]
signal: aborted (core dumped)
</code></pre><p>The last line is what we want to see: it should say “core dumped”.</p>
<p>We can now use <a href="https://manpages.debian.org/coredumpctl.1"><code>coredumpctl(1)</code></a>
 to launch delve for
this program + core dump:</p>
<pre tabindex="0"><code>% coredumpctl debug --debugger=dlv --debugger-arguments=core
           PID: 1729467 (greeter_server)
           UID: 1000 (michael)
           GID: 1000 (michael)
        Signal: 6 (ABRT)
     Timestamp: Sat 2024-10-19 21:50:12 CEST (1min 49s ago)
  Command Line: ./greeter_server
    Executable: /home/michael/go/src/github.com/grpc/grpc-go/examples/helloworld/greeter_server/greeter_server
 Control Group: /user.slice/user-1000.slice/session-1.scope
          Unit: session-1.scope
         Slice: user-1000.slice
       Session: 1
     Owner UID: 1000 (michael)
       Storage: /var/lib/systemd/coredump/core.greeter_server.1000.zst (present)
  Size on Disk: 204.7K
       Message: Process 1729467 (greeter_server) of user 1000 dumped core.
                
                Module /home/michael/go/src/github.com/grpc/grpc-go/examples/helloworld/greeter_server/greeter_server without build-id.
                Stack trace of thread 1729470:
                #0  0x0000000000479461 n/a (greeter_server + 0x79461)
[…]
                ELF object binary architecture: AMD x86-64

Type &#39;help&#39; for list of commands.
(dlv) bt
 0  0x0000000000479461 in runtime.raise
    at /home/michael/sdk/go1.23.0/src/runtime/sys_linux_amd64.s:154
 1  0x0000000000451a85 in runtime.dieFromSignal
    at /home/michael/sdk/go1.23.0/src/runtime/signal_unix.go:942
 2  0x00000000004520e6 in runtime.sigfwdgo
    at /home/michael/sdk/go1.23.0/src/runtime/signal_unix.go:1154
 3  0x0000000000450a85 in runtime.sigtrampgo
    at /home/michael/sdk/go1.23.0/src/runtime/signal_unix.go:432
 4  0x0000000000479461 in runtime.raise
    at /home/michael/sdk/go1.23.0/src/runtime/sys_linux_amd64.s:153
 5  0x0000000000451a85 in runtime.dieFromSignal
    at /home/michael/sdk/go1.23.0/src/runtime/signal_unix.go:942
 6  0x0000000000439551 in runtime.crash
    at /home/michael/sdk/go1.23.0/src/runtime/signal_unix.go:1031
 7  0x0000000000439551 in runtime.fatalpanic
    at /home/michael/sdk/go1.23.0/src/runtime/panic.go:1290
 8  0x000000000046fe88 in runtime.gopanic
    at /home/michael/sdk/go1.23.0/src/runtime/panic.go:804
 9  0x00000000008037ff in main.(*server).SayHello
    at ./main.go:45
10  0x00000000008033a6 in google.golang.org/grpc/examples/helloworld/helloworld._Greeter_SayHello_Handler
    at /home/michael/go/src/github.com/grpc/grpc-go/examples/helloworld/helloworld/helloworld_grpc.pb.go:115
11  0x00000000007edeeb in google.golang.org/grpc.(*Server).processUnaryRPC
    at /home/michael/go/src/github.com/grpc/grpc-go/server.go:1394
12  0x00000000007f2eab in google.golang.org/grpc.(*Server).handleStream
    at /home/michael/go/src/github.com/grpc/grpc-go/server.go:1805
13  0x00000000007ebbff in google.golang.org/grpc.(*Server).serveStreams.func2.1
    at /home/michael/go/src/github.com/grpc/grpc-go/server.go:1029
14  0x0000000000477c21 in runtime.goexit
    at /home/michael/sdk/go1.23.0/src/runtime/asm_amd64.s:1700
(dlv) 
</code></pre><p>Alright! Now let’s switch to frame 9 (our server’s <code>SayHello</code> handler) and
inspect the <code>Name</code> field of the incoming RPC request:</p>
<pre tabindex="0"><code>(dlv) frame 9
&gt; runtime.raise() /home/michael/sdk/go1.23.0/src/runtime/sys_linux_amd64.s:154 (PC: 0x482681)
Warning: debugging optimized function
Frame 9: ./main.go:45 (PC: aaabf8)
    40:	}
    41:	
    42:	// SayHello implements helloworld.GreeterServer
    43:	func (s *server) SayHello(_ context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    44:		log.Printf(&#34;Received: %v&#34;, in.GetName())
=&gt;  45:		panic(&#34;oh no!&#34;)
    46:		return &amp;pb.HelloReply{Message: &#34;Hello &#34; + in.GetName()}, nil
    47:	}
    48:	
    49:	func main() {
    50:		flag.Parse()
(dlv) p in
(&#34;*google.golang.org/grpc/examples/helloworld/helloworld.HelloRequest&#34;)(0xc000120100)
*google.golang.org/grpc/examples/helloworld/helloworld.HelloRequest {
[…]
	unknownFields: []uint8 len: 0, cap: 0, nil,
	Name: &#34;world&#34;,}
</code></pre><p>In this case, it’s easy to see that the <code>Name</code> field was set to <code>world</code> in the
incoming request, but let’s assume the request contained lots of binary data
that was not as easy to read or copy.</p>
<p>How do we write the byte slice contents to a file? In this scenario, we cannot
modify the source code and delve’s <code>call</code> command does not work on core dumps
(only when delve is attached to a running process):</p>
<pre tabindex="0"><code>(dlv) call os.WriteFile(&#34;/tmp/name.raw&#34;, in.Name, 0644)
&gt; runtime.raise() /home/michael/sdk/go1.23.0/src/runtime/sys_linux_amd64.s:154 (PC: 0x482681)
Warning: debugging optimized function
Command failed: can not continue execution of core process
</code></pre><p>Luckily, we can extend delve with a custom Starlark function to write byte slice
contents to a file.</p>
<h2 id="exporting-byte-slices-with-writebytestofile">Exporting byte slices with writebytestofile</h2>
<p>You need a version of dlv that contains commit
<a href="https://github.com/go-delve/delve/commit/52405ba86bd9e14a2e643db391cbdebdcbdb3368">https://github.com/go-delve/delve/commit/52405ba86bd9e14a2e643db391cbdebdcbdb3368</a>. Until
the commit is part of a released version, you can install the latest dlv
directly from git:</p>
<pre tabindex="0"><code>% go install github.com/go-delve/delve/cmd/dlv@master
</code></pre><p>Save the following Starlark code to a file, for example <code>~/dlv_writebytestofile.star</code>:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"># Syntax: writebytestofile &lt;byte slice var&gt; &lt;output file path&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">def</span> <span style="color:#06287e">command_writebytestofile</span>(args):
</span></span><span style="display:flex;"><span>	var_name, filename <span style="color:#666">=</span> args<span style="color:#666">.</span>split(<span style="color:#4070a0">&#34; &#34;</span>)
</span></span><span style="display:flex;"><span>	s <span style="color:#666">=</span> <span style="color:#007020">eval</span>(<span style="color:#007020;font-weight:bold">None</span>, var_name)<span style="color:#666">.</span>Variable
</span></span><span style="display:flex;"><span>	mem <span style="color:#666">=</span> examine_memory(s<span style="color:#666">.</span>Base, s<span style="color:#666">.</span>Len)<span style="color:#666">.</span>Mem
</span></span><span style="display:flex;"><span>	write_file(filename, mem)
</span></span></code></pre></div><p>Then, in delve, load the Starlark code and run the function to export the byte
slice contents of <code>in.Name</code> to <code>/tmp/name.raw</code>:</p>
<pre tabindex="0"><code>% coredumpctl debug --debugger=dlv --debugger-arguments=core
(dlv) frame 9
(dlv) source ~/dlv_writebytestofile.star
(dlv) writebytestofile in.Name /tmp/name.raw
</code></pre><p>Let’s verify that we got the right contents:</p>
<pre tabindex="0"><code>% hexdump -C /tmp/name.raw
00000000  77 6f 72 6c 64                                    |world|
00000005
</code></pre><h2 id="core-dump-debugging-with-nethttp-servers">Core dump debugging with <code>net/http</code> servers</h2>
<p>When you want to apply the core dump debugging technique on a <code>net/http</code> server
(instead of a gRPC server, as above), you will notice that panics in your HTTP
handlers do not actually result in a core dump! This code in
<code>go/src/net/http/server.go</code> recovers panics and logs a stack trace:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">defer</span> <span style="color:#007020;font-weight:bold">func</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#007020">recover</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> <span style="color:#666">&amp;&amp;</span> err <span style="color:#666">!=</span> ErrAbortHandler {
</span></span><span style="display:flex;"><span>        <span style="color:#007020;font-weight:bold">const</span> size = <span style="color:#40a070">64</span> <span style="color:#666">&lt;&lt;</span> <span style="color:#40a070">10</span>
</span></span><span style="display:flex;"><span>        buf <span style="color:#666">:=</span> <span style="color:#007020">make</span>([]<span style="color:#902000">byte</span>, size)
</span></span><span style="display:flex;"><span>        buf = buf[:runtime.<span style="color:#06287e">Stack</span>(buf, <span style="color:#007020;font-weight:bold">false</span>)]
</span></span><span style="display:flex;"><span>        c.server.<span style="color:#06287e">logf</span>(<span style="color:#4070a0">&#34;http: panic serving %v: %v\n%s&#34;</span>, c.remoteAddr, err, buf)
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}()
</span></span></code></pre></div><p>Or, in other words: the <code>GOTRACEBACK=crash</code> environment variable configures what
happens for unhandled signals, but this signal is handled with the <code>recover()</code>
call, so no core is dumped.</p>
<p>This default behavior of <code>net/http</code> servers <a href="https://github.com/golang/go/issues/25245">is now considered regrettable but
cannot be changed for
compatibility</a>. (We probably can add
a struct field to optionally not recover panics, though. I’ll update this
paragraph once there is a proposal.)</p>
<p>So, what options do we have in the meantime?</p>
<p>We could recover panics in our own code (before <code>net/http</code>’s panic handler is
called), but then how do we produce a core dump from our own handler?</p>
<p>A closer look reveals that the Go runtime’s <code>crash</code> function is defined in
<code>signal_unix.go</code> and <a href="https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/runtime/signal_unix.go;l=938">sends signal <code>SIGABRT</code> with the <code>dieFromSignal</code>
function</a>
to the current thread:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic">//go:nosplit
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">crash</span>() {
</span></span><span style="display:flex;"><span>        <span style="color:#06287e">dieFromSignal</span>(_SIGABRT)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>The default action for <code>SIGABRT</code> is to “terminate the process and dump core”,
see <a href="https://manpages.debian.org/signal.7"><code>signal(7)</code></a>
.</p>
<p>We can follow the same strategy and send <code>SIGABRT</code> to our process:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">main</span>() {
</span></span><span style="display:flex;"><span>	http.<span style="color:#06287e">HandleFunc</span>(<span style="color:#4070a0">&#34;/&#34;</span>, <span style="color:#007020;font-weight:bold">func</span>(w http.ResponseWriter, r <span style="color:#666">*</span>http.Request) {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">defer</span> <span style="color:#007020;font-weight:bold">func</span>() {
</span></span><span style="display:flex;"><span>			<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#007020">recover</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>				proc, err <span style="color:#666">:=</span> os.<span style="color:#06287e">FindProcess</span>(syscall.<span style="color:#06287e">Getpid</span>())
</span></span><span style="display:flex;"><span>				<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>					<span style="color:#007020">panic</span>(fmt.<span style="color:#06287e">Sprintf</span>(<span style="color:#4070a0">&#34;could not find own process (pid %d): %v&#34;</span>, syscall.<span style="color:#06287e">Getpid</span>(), err))
</span></span><span style="display:flex;"><span>				}
</span></span><span style="display:flex;"><span>				proc.<span style="color:#06287e">Signal</span>(syscall.SIGABRT)
</span></span><span style="display:flex;"><span>				<span style="color:#60a0b0;font-style:italic">// Ensure the stack triggering the core dump sticks around
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>				proc.<span style="color:#06287e">Wait</span>()
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>		}()
</span></span><span style="display:flex;"><span>		<span style="color:#60a0b0;font-style:italic">// …buggy handler code goes here; for illustration we panic
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>		<span style="color:#007020">panic</span>(<span style="color:#4070a0">&#34;this should result in a core dump&#34;</span>)
</span></span><span style="display:flex;"><span>	})
</span></span><span style="display:flex;"><span>	log.<span style="color:#06287e">Fatal</span>(http.<span style="color:#06287e">ListenAndServe</span>(<span style="color:#4070a0">&#34;:8080&#34;</span>, <span style="color:#007020;font-weight:bold">nil</span>))
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>There is one caveat: If you have any non-Go threads running in your program,
e.g. by using cgo, they might pick up the signal, so ensure they do not install
a <code>SIGABRT</code> handler (see also: <a href="https://pkg.go.dev/os/signal#hdr-Go_programs_that_use_cgo_or_SWIG">cgo-related documentation in
<code>os/signal</code></a>).</p>
<p>If this is a concern, you can make the above code more platform-specific and use
the <a href="https://manpages.debian.org/tgkill.2"><code>tgkill(2)</code></a>
 syscall to direct the signal to the
current thread, as <a href="https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/runtime/sys_linux_amd64.s;l=143">the Go runtime
does</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Core dump debugging can be a very useful technique to quickly make progress on
otherwise hard-to-debug problems. In small environments (single to few Linux
servers), core dumps are easy enough to turn on and work with, but in larger
environments you might need to invest into central core dump collection.</p>
<p>I hope the technique shown above comes in handy when you need to work with core
dumps.</p>


guid: https://michael.stapelberg.ch/posts/2024-11-19-testing-with-go-and-postgresql-ephemeral-dbs/
title: Testing with Go and PostgreSQL: ephemeral DBs
url: https://michael.stapelberg.ch/posts/2024-11-19-testing-with-go-and-postgresql-ephemeral-dbs/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<p><a href="https://en.wikipedia.org/wiki/PostgreSQL" target="_blank"><img
src="postgresql-elephant-featured.png" align="right" width="125"
style="margin-left: 1.5em" alt="PostgreSQL elephant logo"></a></p>
<p>Let’s say you created a Go program that stores data in PostgreSQL — you
installed PostgreSQL, wrote the Go code, and everything works; great!</p>
<p>But after writing a test for your code, you wonder: how do you best provide
PostgreSQL to your automated tests? Do you start a separate PostgreSQL in a
Docker container, for example, or do you maybe reuse your development PostgreSQL
instance?</p>
<p>I have come to like using <strong>ephemeral PostgreSQL instances</strong> for their many benefits:</p>
<ul>
<li>Easier development setup: no need to <em>configure</em> a database, installation is enough.
<br>
I recommend installing PostgreSQL from your package manager, e.g. <code>apt install postgresql</code> (Debian) or <code>brew install postgresql</code> (macOS). No need for Docker :)</li>
<li>No risk of “works on my machine” (but nowhere else) problems: every test run
starts with an empty database instance, so your test <em>must</em> set up the database
correctly.</li>
<li>The same approach works locally and on CI systems like GitHub Actions.</li>
</ul>
<p>In this article, I want to show how to integrate ephemeral PostgreSQL instances
into your test setup. The examples are all specific to Go, but I expect that
users of other programming languages and environments can benefit from some of
these techniques as well.</p>
<h2 id="single-package-tests">Single-package tests</h2>
<p>When you are in the very early stages of your project, you might start out with
just a single test file (say, <code>app_test.go</code>), containing one or more test
functions (say, <code>TestSignupForm</code>).</p>
<p>In this scenario, all tests will run in the same process. While it’s easy enough
to write a few lines of code to start and stop PostgreSQL, I recommend reaching
for an existing test helper package.</p>
<p>Throughout this article, I will be using the
<a href="https://pkg.go.dev/github.com/stapelberg/postgrestest"><code>github.com/stapelberg/postgrestest</code></a>
package, which is based on <a href="https://pkg.go.dev/zombiezen.com/go/postgrestest">Roxy Light’s <code>postgrestest</code>
package</a> but was extended to
work well in the scenarios this article explains.</p>
<p>To start an ephemeral PostgreSQL instance before your test functions run, you
would <a href="https://pkg.go.dev/testing#hdr-Main">declare a custom <code>TestMain</code>
function</a>:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">var</span> pgt <span style="color:#666">*</span>postgrestest.Server
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">TestMain</span>(m <span style="color:#666">*</span>testing.M) {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">var</span> err <span style="color:#902000">error</span>
</span></span><span style="display:flex;"><span>	pgt, err = postgrestest.<span style="color:#06287e">Start</span>(context.<span style="color:#06287e">Background</span>())
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020">panic</span>(err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">defer</span> pgt.<span style="color:#06287e">Cleanup</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	m.<span style="color:#06287e">Run</span>()
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Starting a PostgreSQL instance takes about:</p>
<ul>
<li>300ms on my <a href="/posts/2022-01-15-high-end-linux-pc/">Intel Core i9 12900K CPU</a> (from 2022)</li>
<li>800ms on my <a href="/posts/2021-11-28-macbook-air-m1/">MacBook Air M1</a> (from 2020)</li>
</ul>
<p>Then, you can create a separate database for each test on this ephemeral
Postgres instance:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">TestSignupForm</span>(t <span style="color:#666">*</span>testing.T) {
</span></span><span style="display:flex;"><span>	pgurl, err <span style="color:#666">:=</span> pgt.<span style="color:#06287e">CreateDatabase</span>(context.<span style="color:#06287e">Background</span>())
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		t.<span style="color:#06287e">Fatal</span>(err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// test goes here…
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>}
</span></span></code></pre></div><p>Each CreateDatabase call takes about:</p>
<ul>
<li>5-10ms on my <a href="/posts/2022-01-15-high-end-linux-pc/">Intel Core i9 12900K CPU</a> (from 2022)</li>
<li>20ms on my <a href="/posts/2021-11-28-macbook-air-m1/">MacBook Air M1</a> (from 2020)</li>
</ul>
<p>Usually, most projects quickly grow beyond just a single <code>_test.go</code> file.</p>
<p>In one project if mine, I eventually reached over 50 test functions in 25 Go
packages. I stuck to the above approach of adding a custom <code>TestMain</code> to each
package in which my tests needed PostgreSQL, and my test runtimes eventually
looked like this:</p>
<pre tabindex="0"><code># Intel Core i9 12900K
CGO_ENABLED=0 GOGC=off go test -count=1 -fullpath ./...
14,24s user 4,11s system 709% cpu 2,586 total

# MacBook Air M1
CGO_ENABLED=0 GOGC=off go test -count=1 -fullpath ./...
20,23s user 8,67s system 350% cpu 8,257 total
</code></pre><p>That’s not <em>terrible</em>, but not great either.</p>
<p>If you happen to open a process monitor while running tests, you might have
noticed that there are quite a number of PostgreSQL instances running. This
seems like something to optimize! Shouldn’t one PostgreSQL instance be enough
for all tests of a test run?</p>
<p>Let’s review the process model of <code>go test</code> before we can talk about how to
integrate with it.</p>
<h2 id="go-test-process-model">go test process model</h2>
<p>The usual command to run all tests of a Go project is <code>go test ./...</code> (see <a href="https://pkg.go.dev/cmd/go/internal/help#HelpPackages"><code>go help packages</code></a> for
details on the <code>/...</code> pattern syntax), which matches the Go package in the
current directory and all Go packages in its subdirectories.</p>
<p>Each Go package (≈ directory), including <code>_test.go</code> files, is compiled into a
<em>separate test binary:</em></p>
<pre tabindex="0"><code>% go help test
[…]
&#39;Go test&#39; recompiles each package along with any files with names matching
the file pattern &#34;*_test.go&#34;.
[…]
Each listed package causes the execution of a separate test binary.
[…]
</code></pre><p>These test binaries are then run in parallel. In fact, there are two levels of
parallelism at play here:</p>
<ol>
<li>All test functions (within a single test binary) that call <code>t.Parallel()</code> will be
run in parallel (in batches of size <code>-parallel</code>).</li>
<li><code>go test</code> will run different test binaries in parallel.</li>
</ol>
<p>The documentation explains that the <code>-parallel</code> test flag defaults to
<code>GOMAXPROCS</code> and references the <code>go test</code> parallelism:</p>
<pre tabindex="0"><code>% go help testflag
[…]
-parallel n
    Allow parallel execution of test functions that call t.Parallel, and
    fuzz targets that call t.Parallel when running the seed corpus.
    The value of this flag is the maximum number of tests to run
    simultaneously.
[…]
    By default, -parallel is set to the value of GOMAXPROCS.
    Setting -parallel to values higher than GOMAXPROCS may cause degraded
    performance due to CPU contention, especially when fuzzing.
    Note that -parallel only applies within a single test binary.
    The &#39;go test&#39; command may run tests for different packages
    in parallel as well, according to the setting of the -p flag
    (see &#39;go help build&#39;).
</code></pre><p>The <code>go test</code> parallelism is controlled by the <code>-p</code> flag, which also defaults to
<code>GOMAXPROCS</code>:</p>
<pre tabindex="0"><code>% go help build
[…]
-p n
	the number of programs, such as build commands or
	test binaries, that can be run in parallel.
	The default is GOMAXPROCS, normally the number of CPUs available.
[…]
</code></pre><p>To print <code>GOMAXPROCS</code> on a given machine, we can run a test program like this
<code>gomaxprocs.go</code>:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">package</span> main
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">import</span> <span style="color:#4070a0">&#34;runtime&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#007020">print</span>(runtime.<span style="color:#06287e">GOMAXPROCS</span>(<span style="color:#40a070">0</span>))
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>For me, <code>GOMAXPROCS</code> defaults to the <a href="https://ark.intel.com/content/www/us/en/ark/products/134597/intel-core-i9-12900-processor-30m-cache-up-to-5-10-ghz.html">24 <em>threads</em> of my Intel Core i9 12900K
CPU</a>,
which has 16 <em>cores</em> (8 Performance, 8 Efficiency; only the Performance cores
have Hyper Threading):</p>
<pre tabindex="0"><code>% go run gomaxprocs.go
24
% grep &#39;model name&#39; /proc/cpuinfo | wc -l
24
</code></pre><p>So with a single <code>go test ./...</code> command, we can expect 24 parallel processes
each running 24 tests in parallel. With our current approach, we would start up
to 24 concurrent ephemeral PostgreSQL instances (if we have that many packages),
which seems wasteful to me.</p>
<p>Starting one ephemeral PostgreSQL instance per <code>go test</code> run seems better.</p>
<h2 id="sharing-one-postgresql-among-all-tests">Sharing one PostgreSQL among all tests</h2>
<p>How can we go from starting 24 Postgres instances to starting just one?</p>
<p>First, we need to update our test setup code to work with a passed-in database
URL. For that, we switch from calling
<a href="https://pkg.go.dev/github.com/stapelberg/postgrestest#Server.CreateDatabase"><code>CreateDatabase</code></a>
to using a
<a href="https://pkg.go.dev/github.com/stapelberg/postgrestest#DBCreator"><code>DBCreator</code></a>
for a database identified by a URL. The old code still needs to remain so that
you can run a single test without bothering with <code>PGURL</code>:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">var</span> dbc <span style="color:#666">*</span>postgrestest.DBCreator
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">TestMain</span>(m <span style="color:#666">*</span>testing.M) {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	<span style="color:#60a0b0;font-style:italic">// It is best to specify the PGURL environment variable so that only
</span></span></span><span style="display:flex; background-color:#d8d8d8"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// one PostgreSQL instance is used for all tests.
</span></span></span><span style="display:flex; background-color:#d8d8d8"><span><span style="color:#60a0b0;font-style:italic"></span>	pgurl <span style="color:#666">:=</span> os.<span style="color:#06287e">Getenv</span>(<span style="color:#4070a0">&#34;PGURL&#34;</span>)
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	<span style="color:#007020;font-weight:bold">if</span> pgurl <span style="color:#666">==</span> <span style="color:#4070a0">&#34;&#34;</span> {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>		<span style="color:#60a0b0;font-style:italic">// &#39;go test&#39; was started directly, start one Postgres per process:
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>		pgt, err <span style="color:#666">:=</span> postgrestest.<span style="color:#06287e">Start</span>(context.<span style="color:#06287e">Background</span>())
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#007020">panic</span>(err)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">defer</span> pgt.<span style="color:#06287e">Cleanup</span>()
</span></span><span style="display:flex;"><span>		pgurl = pgt.<span style="color:#06287e">DefaultDatabase</span>()
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	<span style="color:#007020;font-weight:bold">var</span> err <span style="color:#902000">error</span>
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	dbc, err = postgrestest.<span style="color:#06287e">NewDBCreator</span>(pgurl)
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>		<span style="color:#007020">panic</span>(err)
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	m.<span style="color:#06287e">Run</span>()
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<p>Inside the test function(s), we only need to update the <code>CreateDatabase</code>
receiver name:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">TestSignupForm</span>(t <span style="color:#666">*</span>testing.T) {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	pgurl, err <span style="color:#666">:=</span> dbc.<span style="color:#06287e">CreateDatabase</span>(context.<span style="color:#06287e">Background</span>())
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		t.<span style="color:#06287e">Fatal</span>(err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// test goes here…
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>}</span></span></code></pre></div>
<p>Then, we create a new wrapper program (e.g. <code>internal/cmd/initpg/initpg.go</code>)
which calls <code>postgrestest.Start</code> and passes the <code>PGURL</code> environment variable to
the process(es) it starts:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic">// initpg is a small test helper command which starts a Postgres
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic">// instance and makes it available to the wrapped &#39;go test&#39; command.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span><span style="color:#007020;font-weight:bold">package</span> main
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;context&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;log&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;os&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;os/exec&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#4070a0">&#34;github.com/stapelberg/postgrestest&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Use the same database driver as in the rest of your project.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	_ <span style="color:#4070a0">&#34;github.com/lib/pq&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">runWrappedCommand</span>(pgurl <span style="color:#902000">string</span>) <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// os.Args[0] is initpg
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// os.Args[1] is --
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// os.Args[2] is go
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// os.Args[3] is test
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#60a0b0;font-style:italic">// etc.
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	wrapped <span style="color:#666">:=</span> exec.<span style="color:#06287e">Command</span>(os.Args[<span style="color:#40a070">2</span>], os.Args[<span style="color:#40a070">3</span>:]<span style="color:#666">...</span>)
</span></span><span style="display:flex;"><span>	wrapped.Stdin = os.Stdin
</span></span><span style="display:flex;"><span>	wrapped.Stdout = os.Stdout
</span></span><span style="display:flex;"><span>	wrapped.Stderr = os.Stderr
</span></span><span style="display:flex;"><span>	wrapped.Env = <span style="color:#007020">append</span>(os.<span style="color:#06287e">Environ</span>(), <span style="color:#4070a0">&#34;PGURL=&#34;</span><span style="color:#666">+</span>pgurl)
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> wrapped.<span style="color:#06287e">Run</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> fmt.<span style="color:#06287e">Errorf</span>(<span style="color:#4070a0">&#34;%v: %v&#34;</span>, wrapped.Args, err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">return</span> <span style="color:#007020;font-weight:bold">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">initpg</span>() <span style="color:#902000">error</span> {
</span></span><span style="display:flex;"><span>	pgt, err <span style="color:#666">:=</span> postgrestest.<span style="color:#06287e">Start</span>(context.<span style="color:#06287e">Background</span>())
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// NOTE: keep reading the article, do not submit as-is
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">defer</span> pgt.<span style="color:#06287e">Cleanup</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Run the wrapped command (&#39;go test&#39;, typically)
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#007020;font-weight:bold">return</span> <span style="color:#06287e">runWrappedCommand</span>(pgt.<span style="color:#06287e">DefaultDatabase</span>())
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">:=</span> <span style="color:#06287e">initpg</span>(); err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		log.<span style="color:#06287e">Fatal</span>(err)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="running-the-initpg-wrapper-program">Running the initpg wrapper program</h3>
<p>While we could use <code>go run ./internal/cmd/initpg</code> to compile and run this
wrapper program, it is a bit wasteful to recompile this program over and over
when it rarely changes.</p>
<p>One alternative is to use <code>go install</code> instead of <code>go run</code>. I have two minor
concerns with that:</p>
<ol>
<li>
<p><code>go install</code> installs into the bin directory, which is <code>~/go/bin</code> by default.</p>
<ul>
<li>This means we need to rely on the <code>PATH</code> environment variable containing
the bin directory to run the installed program. Unfortunately, influencing
or determining the <code>go install</code> destination path is tricky.</li>
<li>It would be nice to not litter the user’s bin directory. I think the bin
directory should contain programs which the user explicitly requested to
install, not helper programs that are only necessary to run tests.</li>
</ul>
</li>
<li>
<p>On my machine, <code>go install</code> takes about 100ms, even when nothing has changed.</p>
</li>
</ol>
<p>I like to define a <code>Makefile</code> in each of my projects with a set of targets that
are consistently named, e.g. <code>make test</code>, <code>make push</code>, etc. Given that I already
use <code>make</code>, I like to set up my <code>Makefile</code> to build initpg in the <code>_bin</code>
directory:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Makefile" data-lang="Makefile"><span style="display:flex;"><span><span style="color:#06287e">.PHONY</span><span style="color:#666">:</span> test
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06287e">_bin/initpg</span><span style="color:#666">:</span> internal/cmd/initpg/initpg.go
</span></span><span style="display:flex;"><span>	mkdir -p _bin
</span></span><span style="display:flex;"><span>	go build -o _bin/initpg ./internal/cmd/initpg
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#06287e">test</span><span style="color:#666">:</span> _bin/initpg
</span></span><span style="display:flex;"><span>	./_bin/initpg -- go <span style="color:#007020">test</span> ./...
</span></span></code></pre></div><p>Because <code>initpg.go</code> rarely changes, the program will typically not need to be
recompiled.</p>
<p>Note that this <code>Makefile</code> is only approximately correct: <code>initpg</code>’s dependency
on <code>postgrestest</code> is not modeled, so you need to delete <code>_bin/initpg</code> to pick up
changes to <code>postgrestest</code>.</p>
<h2 id="performance">Performance</h2>
<p>Let’s compare the before and after test runtimes on the Intel Core i9 12900K:</p>
<pre tabindex="0"><code># Intel Core i9 12900K: one Postgres for each test
CGO_ENABLED=0 GOGC=off go test -count=1 -fullpath ./...
14,24s user 4,11s system 709% cpu 2,586 total

# Intel Core i9 12900K: one Postgres shared among all tests
CGO_ENABLED=0 GOGC=off ./_bin/initpg -- go test -count=1 -fullpath ./...
11,40s user 3,10s system 659% cpu 2,199 total
</code></pre><p>For comparison, the effect is more pronounced on the MacBook Air M1:</p>
<pre tabindex="0"><code># MacBook Air M1: one Postgres for each test
CGO_ENABLED=0 GOGC=off go test -count=1 -fullpath ./...
20,23s user 8,67s system 350% cpu 8,257 total

# MacBook Air M1: one Postgres shared among all tests
CGO_ENABLED=0 GOGC=off ./_bin/initpg -- go test -count=1 -fullpath ./...
14,25s user 4,36s system 275% cpu 6,752 total
</code></pre><p>Sharing one PostgreSQL instance has reduced the total test runtime for a full
run by about 20%!</p>
<h3 id="why-is-it-sometimes-slower">Why is it sometimes slower?</h3>
<p>We have measurably reduced the runtime of a full test run, but if you pay close
attention during development you will notice that now <strong>every test run is a full
test run</strong>, even when you only change a single package!</p>
<p>Why can Go no longer cache any of the test results? The problem is that the
<code>PGURL</code> environment variable has a different value on each run: the name of the
temporary directory that the <code>postgrestest</code> package uses for its ephemeral
database instance changes on each run.</p>
<p>The documentation on the <code>go test</code> caching behavior explains this in the last
paragraph:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>% go help test
</span></span><span style="display:flex;"><span>[…]
</span></span><span style="display:flex;"><span>In package list mode only, go test caches successful package test
</span></span><span style="display:flex;"><span>results to avoid unnecessary repeated running of tests. When the
</span></span><span style="display:flex;"><span>result of a test can be recovered from the cache, go test will
</span></span><span style="display:flex;"><span>redisplay the previous output instead of running the test binary
</span></span><span style="display:flex;"><span>again. When this happens, go test prints &#39;(cached)&#39; in place of the
</span></span><span style="display:flex;"><span>elapsed time in the summary line.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>The rule for a match in the cache is that the run involves the same
</span></span><span style="display:flex;"><span>test binary and the flags on the command line come entirely from a
</span></span><span style="display:flex;"><span>restricted set of &#39;cacheable&#39; test flags, defined as -benchtime, -cpu,
</span></span><span style="display:flex;"><span>-list, -parallel, -run, -short, -timeout, -failfast, -fullpath and -v.
</span></span><span style="display:flex;"><span>If a run of go test has any test or non-test flags outside this set,
</span></span><span style="display:flex;"><span>the result is not cached. To disable test caching, use any test flag
</span></span><span style="display:flex;"><span>or argument other than the cacheable flags. The idiomatic way to disable
</span></span><span style="display:flex;"><span>test caching explicitly is to use -count=1.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Tests that open files within the package&#39;s source root (usually $GOPATH)
</span></span><span style="display:flex; background-color:#d8d8d8"><span>or that consult environment variables only match future runs in which
</span></span><span style="display:flex; background-color:#d8d8d8"><span>the files and environment variables are unchanged.
</span></span><span style="display:flex;"><span>[…]</span></span></code></pre></div>
<p>(See also <a href="https://github.com/golang/go/issues/22593">Go issue #22593</a> for more details.)</p>
<h3 id="fixing-go-test-caching-env-vars">Fixing Go test caching (env vars)</h3>
<p>For the Go test caching to work, all environment variables our tests access
(including <code>PGURL</code>) need to contain the same value between runs. For us, this
means we cannot use a randomly generated name for the Postgres data directory,
but instead need to use a fixed name.</p>
<p>My <code>postgrestest</code> package offers convenient support for specifying the desired
directory:</p>
<div class="highlight"><pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#007020;font-weight:bold">func</span> <span style="color:#06287e">initpg</span>() <span style="color:#902000">error</span> {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	cacheDir, err <span style="color:#666">:=</span> os.<span style="color:#06287e">UserCacheDir</span>()
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex; background-color:#d8d8d8"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	}
</span></span><span style="display:flex; background-color:#d8d8d8"><span>	pgt, err <span style="color:#666">:=</span> postgrestest.<span style="color:#06287e">Start</span>(context.<span style="color:#06287e">Background</span>(),
</span></span><span style="display:flex; background-color:#d8d8d8"><span>		postgrestest.<span style="color:#06287e">WithDir</span>(filepath.<span style="color:#06287e">Join</span>(cacheDir, <span style="color:#4070a0">&#34;initpg.gus&#34;</span>)))
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">if</span> err <span style="color:#666">!=</span> <span style="color:#007020;font-weight:bold">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#007020;font-weight:bold">return</span> err
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#007020;font-weight:bold">defer</span> pgt.<span style="color:#06287e">Cleanup</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#60a0b0;font-style:italic">// Run the wrapped command (&#39;go test&#39;, typically)
</span></span></span><span style="display:flex;"><span><span style="color:#60a0b0;font-style:italic"></span>	<span style="color:#007020;font-weight:bold">return</span> <span style="color:#06287e">runWrappedCommand</span>(pgt.<span style="color:#06287e">DefaultDatabase</span>())
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<p>When running the tests now, starting with the second run (without any changes),
you should see a “ (cached)” suffix printed behind tests that were successfully
cached, and the test runtime should be much shorter — under a second in my
project:</p>
<pre tabindex="0"><code>% time ./_bin/initpg -- go test -fullpath ./...
ok  	example/internal/handlers/adminhandler	(cached)
[…]
./_bin/initpg -- go test -fullpath ./...
1,30s user 0,88s system 288% cpu 0,756 total
</code></pre><h2 id="conclusion">Conclusion</h2>
<p>In this article, I have shown how to integrate PostgreSQL into your test
environment in a way that is convenient for developers, light on system
resources and measurably reduces total test time.</p>
<p>Adopting <code>postgrestest</code> seems easy enough to me. If you want to see a complete
example, see <a href="https://github.com/gokrazy/gus/commit/b97c652fd03754ba817bd3c13f18ea6e2e154ef4">how I converted the <code>gokrazy/gus</code> repository to use
<code>postgrestest</code></a>.</p>
<h2 id="further-optimization-potential">Further optimization potential</h2>
<p>Now that we have a detailed understanding of the <code>go test</code> process model and
PostgreSQL startup, we can consider further optimizations. I won’t actually
implement them in this article, which is already long enough, but maybe you want
to go further in your project…</p>
<h3 id="hide-postgres-startup">Hide Postgres startup</h3>
<p>My journey into ephemeral PostgreSQL instances started with <a href="https://eradman.com/ephemeralpg/">Eric Radman’s
<code>pg_tmp</code> shell script</a>. Ultimately, I ended up
with the <code>postgrestest</code> Go solution that I much prefer: I don’t need to ship (or
require) the <code>pg_tmp</code> shell script with my projects. The fewer languages, the
better.</p>
<p>Also, <code>pg_tmp</code> is not a wrapper program, which resulted in problems regarding
cleanup: A wrapper program can reliably trigger cleanup when tests are done,
whereas <code>pg_tmp</code> has to poll for activity. Polling is prone to running too
quickly (cleaning up a database before tests were even started) or too slowly,
requiring constant tuning.</p>
<p>But, <code>pg_tmp</code> does have quite a clever concept of preparing PostgreSQL instances
in the background and thereby amortizing startup costs between test runs.</p>
<p>There might be an even simpler approach that could amount to the same startup
latency hiding behavior: Turning the sequential startup (<code>initpg</code> needs to wait
for PostgreSQL to start and only then can begin running <code>go test</code>) into parallel
startup using Socket Activation.</p>
<p>Note that PostgreSQL does not seem to support Socket Activation natively, so
probably one would need to implement a program-agnostic solution into <code>initpg</code>
as described in this <a href="https://unix.stackexchange.com/questions/352495/systemd-on-demand-start-of-services-like-postgresql-and-mysql-that-do-not-yet-s">Unix Stack Exchange
question</a>
or <a href="https://andreas.rammhold.de/posts/postgresql-tmpfs-with-sytemdsocket-activation-for-local-ephemeral-data-during-development/">Andreas Rammhold’s blog
post</a>.</p>
<h3 id="de-duplicate-schema-creation-cost">De-duplicate schema creation cost</h3>
<p>For isolation, we use a different PostgreSQL database for every test. This means
we need to initialize the database schema for each of these per-test databases.</p>
<p>We can eliminate this duplicative work by <strong>sharing the same database</strong> across
all tests, provided we have another way of isolating the tests from each other.</p>
<p>The <a href="https://github.com/DATA-DOG/go-txdb"><code>txdb</code> package</a> provides a standard
<code>database/sql.Driver</code> which runs all queries of an entire test in a single
transaction. Using <code>txdb</code> means we can now safely share the same database
between tests without running into conflicts, failing tests, or needing extra
locking.</p>
<p>Be sure to initialize the database schema <em>before</em> using <code>txdb</code> to share the
database: long-running transactions needs to lock the PostgreSQL catalog as soon
as you change the database schema (i.e. create or modify tables), meaning only
one test can run at a time. (Using <a href="https://sourcegraph.com/blog/go/an-introduction-to-go-tool-trace-rhys-hiltner"><code>go tool trace</code></a>
is a great way to understand such performance issues.)</p>
<p>I am aware that some people don’t like the transaction isolation approach. For
example, <a href="https://gajus.com/blog/setting-up-postgre-sql-for-running-integration-tests">Gajus Kuizinas’s blog post “Setting up PostgreSQL for running
integration
tests”</a>
finds that transactions don’t work in their (JavaScript) setup. I don’t share
this experience at all: In Go, the <a href="https://github.com/DATA-DOG/go-txdb"><code>txdb</code>
package</a> works well, even with nested
transactions. I have used <code>txdb</code> for months without problems.</p>
<p>In my tests, eliminating this duplicative schema initialization work saves
about:</p>
<ul>
<li>0.5s on my Intel Core i9 12900K</li>
<li>1s on the MacBook Air M1</li>
</ul>


guid: https://michael.stapelberg.ch/posts/2024-12-10-solar-panel-for-your-balcony/
title: Get a solar panel for your balcony now ☀️
url: https://michael.stapelberg.ch/posts/2024-12-10-solar-panel-for-your-balcony/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<p>A year ago, I got a solar panel for my balcony — an easy way to vote with your
wallet to convert more of the world’s energy usage to solar power. That was a
great decision and I would recommend everyone get a solar panel (or two)!</p>
<h2 id="its-called-plug-in-solar-panel-because-you-can-just-plug-it-in">It’s called plug-in solar panel because you can just plug it in</h2>
<p>In my experience, many people are surprised about the basics of how power works:
You do not need to connect devices to a battery in order to enjoy solar
power. You can just plug in the solar panel into your household electricity
setup. Any of your consumers (like a TV, or electric cooktop) will now use the
power that your solar panel produces before consuming power from the grid.</p>
<p>Here’s the panel I have (Weber barbecue for scale). As you can see, the panel is
not yet mounted at an angle, just hung over the balcony. The black box at the
back of the panel is the inverter (“Wechselrichter”). You connect the panel on
one side and get electricity out the other side.</p>
<p><img src="IMG_2882.jpg" alt=""></p>
<h2 id="which-solar-panel-to-buy">Which solar panel to buy?</h2>
<p>There are two big questions to answer when chosing a solar panel: what peak
capacity should your panel(s) have and which company / seller do you buy from?</p>
<p>Regarding panel capacity: When I look at my energy usage, I see about 100 watts
of baseline load. This includes always-on servers and other home automation
devices. During working hours, running a PC and (power-hungry) monitor adds
another 100 watts or so. Around noon, there is quite a spike in usage when
cooking with my induction cooktop.</p>
<p>Hence, I figured a plug &amp; play solar panel with the smallest size of 385 Wp
would be well equipped to cover baseline usage, compared to the next bigger unit
with 780 Wp, which seems oversized for my usage. Note that a peak capacity of
385 Wp will not necessarily mean that you will measure 380W of output. I did
repeatedly measure energy production exceeding 300W.</p>
<p>Regarding the company, the best offer I found in Switzerland was a small company
called <a href="https://www.erneuer.bar/">erneuer.bar</a>, which means “renewable” in
German. They ship the panels with barely any packaging in fully electric
vehicles and their offer is eligible for <a href="https://www.topten.ch/private/page/ewz">the topten bonus program from
EWZ</a>, meaning you’ll get back 200 CHF if
you fill in a form.</p>
<p>The specific model I ordered was called “385 Wp Plug &amp; Play Solar (DE)”. Here’s
the bill:</p>
<table>
<thead>
<tr>
<th>Produkt</th>
<th>Preis</th>
</tr>
</thead>
<tbody>
<tr>
<td>385 Wp Plug &amp; Play Solar (DE)</td>
<td>CHF 520.00</td>
</tr>
<tr>
<td>Mounting kit: balcony, 1 panel</td>
<td>CHF 75.00</td>
</tr>
<tr>
<td>Pre-mount: mounting kit balcony</td>
<td>CHF 60.00</td>
</tr>
<tr>
<td>WiFi measurement myStrom</td>
<td>CHF 55.00</td>
</tr>
<tr>
<td>Shipping</td>
<td>CHF 68.00</td>
</tr>
<tr>
<td>Total</td>
<td>CHF 778.00</td>
</tr>
</tbody>
</table>
<p>Of course, you can save some money in various ways. For example, the measurement
device and pre-mount option are both not required, but convenient. Similarly,
you can probably find solar panels for cheaper, but the offer that erneuer.bar
has put together truly is very convenient and works well, and to me that’s worth
some money.</p>
<p>One mistake I made when ordering is selecting a 5m cable. It turned out I needed
a 10m cable, so I recommend you measure better than I did (or just select the
longer cable). On the plus side, customer service was excellent: I quickly
received an email response and could just send back my cable in exchange for a
new one.</p>
<h2 id="amortization-who-cares">Amortization? Who cares!</h2>
<p>Many people seem to consider <strong>only the financial aspect</strong> of buying a solar
panel and calculate when the solar panel will have paid for itself. I don’t
care. My goal is to convert more energy usage to green energy, not to save
money.</p>
<p>Similarly, some people install batteries so that they can use “their” energy for
themselves, in case the solar panel produces more than they use at that
moment. I couldn’t care less who uses the energy I produce — as long as it’s
green energy, anyone is welcome to consume it.</p>
<p>(Of course I understand these questions become more important the larger a solar
installation gets. But we’re talking about one balcony and one solar panel (or
two) covering someone’s baseline residential household electricity load. Don’t
overthink it!)</p>
<h2 id="requirement-balcony-power-socket">Requirement: balcony power socket</h2>
<p>Aside from having a balcony, there is only one hard requirement: you need a
power socket.</p>
<p>This requirement is either trivially fulfilled if you already have an outdoor
power socket on your balcony (lucky you!), or might turn out to be the most
involved part of the project. Either way, because an electrician needs to
install power sockets, all you can do is get permission from your landlord and
make an appointment with your electrician of choice.</p>
<p>In terms of cost, you will probably spend a few hundred bucks, depending on your
area’s cost of living. A good idea that did not occur to me back then: Ask
around in your house if any neighbors would be interested in getting a balcony
power socket, too, and do it all in one go (for cheaper).</p>
<h2 id="bureaucracy">Bureaucracy</h2>
<p>One can easily find stories online about electricity providers and landlords not
permitting the installation of solar panels for… rather questionable
reasons. For example, some claimed that solar panels could overload the house
electricity infrastructure! A drastic-sounding claim, but nonsense in
practice. Luckily, law makers are recognizing this and are removing barriers.</p>
<h3 id="electricity-provider-and-the-law">Electricity provider and the law</h3>
<p>In Switzerland 🇨🇭, you can connect panels producing up to 600W without an
electrician, but you need to notify your electricity provider.</p>
<p>In Germany 🇩🇪, you can connect panels producing up to 800W (as of May 16th 2024)
without an electrician, but <a href="https://www.adac.de/rund-ums-haus/energie/versorgung/balkonkraftwerk-anmelden/">you need to register with the
Bundesnetzagentur</a>.</p>
<p>Be sure to check your country’s laws and your electricity provider’s rules and
processes.</p>
<h3 id="landlord-and-neighbors">Landlord and neighbors</h3>
<p>In Switzerland 🇨🇭, you need to <a href="https://www.mieterverband.ch/mv/politik-positionen/news/2024/mustervereinbarung-fuer-bewilligung-von-balkonsolaranlagen.html">ask your landlord for
permission</a>
because if your solar panel were to fall down from the balcony, the landlord
would be liable. Usually, the landlord insists on proper mounting and the tenant
taking over liability. In my case, the landlord also asked me to ensure the
neighbors wouldn’t mind. I put up a letter, nobody complained, the landlord
accepted.</p>
<p>In Germany 🇩🇪, you do need to ask your landlord for permission, but the landlord
pretty much has to agree (<a href="https://www.computerbild.de/artikel/cb-News-Energie-Bundeskabinett-Balkonkraftwerk-Wohnung-Privileg-36684829.html">as of October 17th
2024</a>). The
question is not “if”, but “how” the landlord wants you to install the solar
panel.</p>
<h2 id="optimizing-the-installation-angle">Optimizing the installation angle</h2>
<p>Earlier I wrote that you can just hang the solar panel onto your balcony and
plug it in. While this is true, there is one factor that is worth optimizing (as
time permits): the installation angle.</p>
<p>If you want more details about the physics background and various considerations
that go into chasing the optimal angle, check out these (German) articles about
<a href="https://www.golem.de/news/balkonkraftwerke-was-bringt-der-neigungswinkel-fuer-den-stromertrag-2405-185599-2.html">optimizing the installation angle (at
Golem)</a>
or <a href="https://www.heise.de/ratgeber/Photovoltaik-Anlagen-dimensionieren-Wirtschaftlichkeit-berechnen-9688108.html?seite=2">sizing solar installations (at
Heise)</a>. I’ll
summarize: the angle is important and can result in twice as much energy
production! Any angle is usually better than no angle.</p>
<p>In my case, I first “installed” the solar panel (no angle) at 2023-09-30.</p>
<p>Then, about a month later, I installed it at an angle at 2023-10-28.</p>
<p><img src="IMG_2996.jpg" alt=""></p>
<p>I unfortunately don’t have a great before/after graph because after I installed
the proper angle mount, there were almost no sunny days.</p>
<p>Instead, I will show you data from a comparable time range (early October) in
2023 (before mounting the panel at an angle) and in 2024 (with a properly
mounted panel). As you can see, the difference is not that huge, but clearly
visible: without an angle mount, I could never exceed 300 Wh per day. With a
proper mount, a number of days exceed 300 Wh:</p>
<table>
<thead>
<tr>
<th></th>
<th>1st</th>
<th>2nd</th>
<th>3rd</th>
<th>4th</th>
<th>5th</th>
<th>6th</th>
<th>7th</th>
<th>8th</th>
<th>9th</th>
<th>10th</th>
</tr>
</thead>
<tbody>
<tr>
<td>2023 🌞 Wh</td>
<td>133</td>
<td>268</td>
<td>262</td>
<td>208</td>
<td>271</td>
<td>255</td>
<td>274</td>
<td>277</td>
<td>275</td>
<td>194</td>
</tr>
<tr>
<td>2024 🌞 Wh</td>
<td>529</td>
<td>119</td>
<td>246</td>
<td>205</td>
<td>160</td>
<td>324</td>
<td>265</td>
<td>335</td>
<td>73</td>
<td>444</td>
</tr>
</tbody>
</table>
<h2 id="how-much-electricity-does-my-panel-generate">How much electricity does my panel generate?</h2>
<p>The exact electricity production numbers depend on how much sun ends up on the
solar panel. This in turn depends on the weather and how obstructed the solar
panel is (neighbors, trees, …).</p>
<p>I like measuring things, so I will share some measurements to give you a rough
idea. But note that measuring your solar panel is strictly optional.</p>
<p>On the best recorded day, my panel produced about 1.680 kWh of energy:</p>
<p><img src="2024-06-05-1680Wh.jpg" alt=""></p>
<p>The missing parts before 14:00 are caused by the neighbor’s house blocking the sun.</p>
<p>Now, compare this best case with the worst case, a January day with little sun
(&lt; 50 Wh):</p>
<p><img src="2024-12-04-solar-january-14th.jpg" alt=""></p>
<p>Let’s zoom out a bit and consider an entire year instead.</p>
<p>In 2024, the panel produced over 177 kWh so far, or, averaged to the daily
value, ≈0.5 kWh/day:</p>
<p><img src="2024-12-04-solar-whole-year.jpg" alt=""></p>
<p>Or, in numeric form (all numbers in kWh):</p>
<table>
<thead>
<tr>
<th>Jan</th>
<th>Feb</th>
<th>Mar</th>
<th>Apr</th>
<th>May</th>
<th>Jun</th>
<th>Jul</th>
<th>Aug</th>
<th>Sep</th>
<th>Oct</th>
<th>Nov</th>
<th>Dec</th>
</tr>
</thead>
<tbody>
<tr>
<td>2.9</td>
<td>6.6</td>
<td>10.9</td>
<td>18.4</td>
<td>29.1</td>
<td>27.7</td>
<td>37.6</td>
<td>22.1</td>
<td>12.0</td>
<td>6.5</td>
<td>3.3</td>
<td>n/a</td>
</tr>
</tbody>
</table>
<!--

% for f in *.csv; do head -2 "$f"; (IFS=$'\n'; for measure in $(cut -d, -f2 "$f" |grep Wh); do units -t "$measure" Wh; done | tr '\n' '+'; echo 0) | bc; done 

| Month   | Solar energy (kWh) |
|---------|--------------------|
| 2024-01 | 2.901              |
| 2024-02 | 6.614              |
| 2024-03 | 10.956             |
| 2024-04 | 18.451             |
| 2024-05 | 29.150             |
| 2024-06 | 27.743             |
| 2024-07 | 37.683             |
| 2024-08 | 22.128             |
| 2024-09 | 12.074             |
| 2024-10 | 6.521              |
| 2024-11 | 3.361              |

-->
<h2 id="conclusion">Conclusion</h2>
<p>A solar panel is a great project to make incremental progress on. It’s just 3 to
4 simple steps, each of which is valuable on its own:</p>
<ol>
<li>Check with your landlord that installing an outdoor power socket and solar panel is okay.
<ul>
<li>Even if you personally do not go any further with your project, you can
share the result with your neighbors, who might…</li>
</ul>
</li>
<li>Order an outdoor power socket from your (or your landlord’s) preferred electrician.
<ul>
<li>Power will come in handy for lighting when spending summer evenings on the
balcony.</li>
</ul>
</li>
<li>Order a solar panel and plug it in.</li>
<li>Optional, but recommended: Optimize the mounting angle later.</li>
</ol>
<p>That’s it! Come on, get started right away 🌞</p>


guid: https://michael.stapelberg.ch/posts/2024-12-21-go-protobuf-opaque/
title: Go Protobuf: The new Opaque API
url: https://michael.stapelberg.ch/posts/2024-12-21-go-protobuf-opaque/
feedurl: https://michael.stapelberg.ch/feed.xml
content_mime_type: text/html
content:
<aside class="admonition note">
  <div class="note-container">
    <div class="note-icon" style="width: 20px; height: 20px">
      <svg id="exclamation-icon" width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
    <path d="M0,0L24,0L24,24L0,24L0,0Z" style="fill:none;"/>
    <g transform="matrix(1.2,0,0,1.2,-2.4,-2.4)">
        <path d="M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2ZM13,17L11,17L11,15L13,15L13,17ZM13,13L11,13L11,7L13,7L13,13Z" style="fill-rule:nonzero;"/>
    </g>
</svg>

    </div>
    <div class="admonition-content">I originally published this post in <a href="https://go.dev/blog">the Go blog</a>, but am
publishing this copy of it in my own blog as well for readers who don’t follow
the Go blog.</div>
  </div>
</aside>

<p>[<a href="https://en.wikipedia.org/wiki/Protocol_Buffers">Protocol Buffers (Protobuf)</a>
is Google&rsquo;s language-neutral data interchange format. See
<a href="https://protobuf.dev/">protobuf.dev</a>.]</p>
<p>Back in March 2020, we released <a href="https://go.dev/blog/protobuf-apiv2">a major overhaul of the Go Protobuf
API</a>. The <code>google.golang.org/protobuf</code>
package introduced first-class <a href="https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect">support for
reflection</a>,
a <a href="https://pkg.go.dev/google.golang.org/protobuf/types/dynamicpb"><code>dynamicpb</code></a>
implementation and the
<a href="https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp"><code>protocmp</code></a>
package for easier testing.</p>
<p>That release introduced a new protobuf module with a new API. Today, we are
releasing an additional API for generated code, meaning the Go code in the
<code>.pb.go</code> files created by the protocol compiler (<code>protoc</code>). This blog post
explains our motivation for creating a new API and shows you how to use it in
your projects.</p>
<p>To be clear: We are not removing anything. We will continue to support the
existing API for generated code, just like we still support the older protobuf
module (by wrapping the <code>google.golang.org/protobuf</code> implementation). Go is
<a href="https://go.dev/blog/compat">committed to backwards compatibility</a> and this
applies to Go Protobuf, too!</p>
<h2 id="background">Background: the (existing) Open Struct API</h2>
<p>We now call the existing API the Open Struct API, because generated struct types
are open to direct access. In the next section, we will see how it differs from
the new Opaque API.</p>
<p>To work with protocol buffers, you first create a <code>.proto</code> definition file like
this one:</p>
<pre><code>edition = &quot;2023&quot;;  // successor to proto2 and proto3

package log;

message LogEntry {
  string backend_server = 1;
  uint32 request_size = 2;
  string ip_address = 3;
}
</code></pre>
<p>Then, you <a href="https://protobuf.dev/getting-started/gotutorial/">run the protocol compiler
(<code>protoc</code>)</a> to generate code
like the following (in a <code>.pb.go</code> file):</p>
<pre><code>package logpb

type LogEntry struct {
  BackendServer *string
  RequestSize   *uint32
  IPAddress     *string
  // …internal fields elided…
}

func (l *LogEntry) GetBackendServer() string { … }
func (l *LogEntry) GetRequestSize() uint32   { … }
func (l *LogEntry) GetIPAddress() string     { … }
</code></pre>
<p>Now you can import the generated <code>logpb</code> package from your Go code and call
functions like
<a href="https://pkg.go.dev/google.golang.org/protobuf/proto#Marshal"><code>proto.Marshal</code></a>
to encode <code>logpb.LogEntry</code> messages into protobuf wire format.</p>
<p>You can find more details in the <a href="https://protobuf.dev/reference/go/go-generated/">Generated Code API
documentation</a>.</p>
<h3 id="presence">(Existing) Open Struct API: Field Presence</h3>
<p>An important aspect of this generated code is how <em>field presence</em> (whether a
field is set or not) is modeled. For instance, the above example models presence
using pointers, so you could set the <code>BackendServer</code> field to:</p>
<ol>
<li><code>proto.String(&quot;zrh01.prod&quot;)</code>: the field is set and contains &ldquo;zrh01.prod&rdquo;</li>
<li><code>proto.String(&quot;&quot;)</code>: the field is set (non-<code>nil</code> pointer) but contains an
empty value</li>
<li><code>nil</code> pointer: the field is not set</li>
</ol>
<p>If you are used to generated code not having pointers, you are probably using
<code>.proto</code> files that start with <code>syntax = &quot;proto3&quot;</code>. The field presence behavior
changed over the years:</p>
<ul>
<li><code>syntax = &quot;proto2&quot;</code> uses <em>explicit presence</em> by default</li>
<li><code>syntax = &quot;proto3&quot;</code> used <em>implicit presence</em> by default (where cases 2 and 3
cannot be distinguished and are both represented by an empty string), but was
later extended to allow <a href="https://protobuf.dev/programming-guides/proto3/#field-labels">opting into explicit presence with the <code>optional</code>
keyword</a></li>
<li><code>edition = &quot;2023&quot;</code>, the <a href="https://protobuf.dev/editions/overview/">successor to both proto2 and
proto3</a>, uses <a href="https://protobuf.dev/programming-guides/field_presence/"><em>explicit
presence</em></a> by default</li>
</ul>
<h2 id="opaqueapi">The new Opaque API</h2>
<p>We created the new <em>Opaque API</em> to uncouple the <a href="https://protobuf.dev/reference/go/go-generated/">Generated Code
API</a> from the underlying
in-memory representation. The (existing) Open Struct API has no such separation:
it allows programs direct access to the protobuf message memory. For example,
one could use the <code>flag</code> package to parse command-line flag values into protobuf
message fields:</p>
<pre><code>var req logpb.LogEntry
flag.StringVar(&amp;req.BackendServer, &quot;backend&quot;, os.Getenv(&quot;HOST&quot;), &quot;…&quot;)
flag.Parse() // fills the BackendServer field from -backend flag
</code></pre>
<p>The problem with such a tight coupling is that we can never change how we lay
out protobuf messages in memory. Lifting this restriction enables many
implementation improvements, which we&rsquo;ll see below.</p>
<p>What changes with the new Opaque API? Here is how the generated code from the
above example would change:</p>
<pre><code>package logpb

type LogEntry struct {
  xxx_hidden_BackendServer *string // no longer exported
  xxx_hidden_RequestSize   uint32  // no longer exported
  xxx_hidden_IPAddress     *string // no longer exported
  // …internal fields elided…
}

func (l *LogEntry) GetBackendServer() string { … }
func (l *LogEntry) HasBackendServer() bool   { … }
func (l *LogEntry) SetBackendServer(string)  { … }
func (l *LogEntry) ClearBackendServer()      { … }
// …
</code></pre>
<p>With the Opaque API, the struct fields are hidden and can no longer be
directly accessed. Instead, the new accessor methods allow for getting, setting,
or clearing a field.</p>
<h3 id="lessmemory">Opaque structs use less memory</h3>
<p>One change we made to the memory layout is to model field presence for
elementary fields more efficiently:</p>
<ul>
<li>The (existing) Open Struct API uses pointers, which adds a 64-bit word to the
space cost of the field.</li>
<li>The Opaque API uses <a href="https://en.wikipedia.org/wiki/Bit_field">bit
fields</a>, which require one bit per
field (ignoring padding overhead).</li>
</ul>
<p>Using fewer variables and pointers also lowers load on the allocator and on the
garbage collector.</p>
<p>The performance improvement depends heavily on the shapes of your protocol
messages: The change only affects elementary fields like integers, bools, enums,
and floats, but not strings, repeated fields, or submessages (because it is
<a href="https://protobuf.dev/reference/go/opaque-faq/#memorylayout">less
profitable</a>
for those types).</p>
<p>Our benchmark results show that messages with few elementary fields exhibit
performance that is as good as before, whereas messages with more elementary
fields are decoded with significantly fewer allocations:</p>
<pre><code>             │ Open Struct API │             Opaque API             │
             │    allocs/op    │  allocs/op   vs base               │
Prod#1          360.3k ± 0%       360.3k ± 0%  +0.00% (p=0.002 n=6)
Search#1       1413.7k ± 0%       762.3k ± 0%  -46.08% (p=0.002 n=6)
Search#2        314.8k ± 0%       132.4k ± 0%  -57.95% (p=0.002 n=6)
</code></pre>
<p>Reducing allocations also makes decoding protobuf messages more efficient:</p>
<pre><code>             │ Open Struct API │             Opaque API            │
             │   user-sec/op   │ user-sec/op  vs base              │
Prod#1         55.55m ± 6%        55.28m ± 4%  ~ (p=0.180 n=6)
Search#1       324.3m ± 22%       292.0m ± 6%  -9.97% (p=0.015 n=6)
Search#2       67.53m ± 10%       45.04m ± 8%  -33.29% (p=0.002 n=6)
</code></pre>
<p>(All measurements done on an AMD Castle Peak Zen 2. Results on ARM and Intel
CPUs are similar.)</p>
<p>Note: proto3 with implicit presence similarly does not use pointers, so you will
not see a performance improvement if you are coming from proto3. If you were
using implicit presence for performance reasons, forgoing the convenience of
being able to distinguish empty fields from unset ones, then the Opaque API now
makes it possible to use explicit presence without a performance penalty.</p>
<h3 id="lazydecoding">Motivation: Lazy Decoding</h3>
<p>Lazy decoding is a performance optimization where the contents of a submessage
are decoded when first accessed instead of during
<a href="https://pkg.go.dev/google.golang.org/protobuf/proto#Unmarshal"><code>proto.Unmarshal</code></a>. Lazy
decoding can improve performance by avoiding unnecessarily decoding fields which
are never accessed.</p>
<p>Lazy decoding can&rsquo;t be supported safely by the (existing) Open Struct API. While
the Open Struct API provides getters, leaving the (un-decoded) struct fields
exposed would be extremely error-prone. To ensure that the decoding logic runs
immediately before the field is first accessed, we must make the field private
and mediate all accesses to it through getter and setter functions.</p>
<p>This approach made it possible to implement lazy decoding with the Opaque
API. Of course, not every workload will benefit from this optimization, but for
those that do benefit, the results can be spectacular: We have seen logs
analysis pipelines that discard messages based on a top-level message condition
(e.g. whether <code>backend_server</code> is one of the machines running a new Linux kernel
version) and can skip decoding deeply nested subtrees of messages.</p>
<p>As an example, here are the results of the micro-benchmark we included,
demonstrating how lazy decoding saves over 50% of the work and over 87% of
allocations!</p>
<pre><code>                  │   nolazy    │                lazy                │
                  │   sec/op    │   sec/op     vs base               │
Unmarshal/lazy-24   6.742µ ± 0%   2.816µ ± 0%  -58.23% (p=0.002 n=6)

                  │    nolazy    │                lazy                 │
                  │     B/op     │     B/op      vs base               │
Unmarshal/lazy-24   3.666Ki ± 0%   1.814Ki ± 0%  -50.51% (p=0.002 n=6)

                  │   nolazy    │               lazy                │
                  │  allocs/op  │ allocs/op   vs base               │
Unmarshal/lazy-24   64.000 ± 0%   8.000 ± 0%  -87.50% (p=0.002 n=6)
</code></pre>
<h3 id="pointercomparison">Motivation: reduce pointer comparison mistakes</h3>
<p>Modeling field presence with pointers invites pointer-related bugs.</p>
<p>Consider an enum, declared within the <code>LogEntry</code> message:</p>
<pre><code>message LogEntry {
  enum DeviceType {
    DESKTOP = 0;
    MOBILE = 1;
    VR = 2;
  };
  DeviceType device_type = 1;
}
</code></pre>
<p>A simple mistake is to compare the <code>device_type</code> enum field like so:</p>
<pre><code>if cv.DeviceType == logpb.LogEntry_DESKTOP.Enum() { // incorrect!
</code></pre>
<p>Did you spot the bug? The condition compares the memory address instead of the
value. Because the <code>Enum()</code> accessor allocates a new variable on each call, the
condition can never be true. The check should have read:</p>
<pre><code>if cv.GetDeviceType() == logpb.LogEntry_DESKTOP {
</code></pre>
<p>The new Opaque API prevents this mistake: Because fields are hidden, all access
must go through the getter.</p>
<h3 id="accidentalsharing">Motivation: reduce accidental sharing mistakes</h3>
<p>Let&rsquo;s consider a slightly more involved pointer-related bug. Assume you are
trying to stabilize an RPC service that fails under high load. The following
part of the request middleware looks correct, but still the entire service goes
down whenever just one customer sends a high volume of requests:</p>
<pre><code>logEntry.IPAddress = req.IPAddress
logEntry.BackendServer = proto.String(hostname)
// The redactIP() function redacts IPAddress to 127.0.0.1,
// unexpectedly not just in logEntry *but also* in req!
go auditlog(redactIP(logEntry))
if quotaExceeded(req) {
	// BUG: All requests end up here, regardless of their source.
	return fmt.Errorf(&quot;server overloaded&quot;)
}
</code></pre>
<p>Did you spot the bug? The first line accidentally copied the pointer (thereby
sharing the pointed-to variable between the <code>logEntry</code> and <code>req</code> messages)
instead of its value. It should have read:</p>
<pre><code>logEntry.IPAddress = proto.String(req.GetIPAddress())
</code></pre>
<p>The new Opaque API prevents this problem as the setter takes a value
(<code>string</code>) instead of a pointer:</p>
<pre><code>logEntry.SetIPAddress(req.GetIPAddress())
</code></pre>
<h3 id="reflection">Motivation: Fix Sharp Edges: reflection</h3>
<p>To write code that works not only with a specific message type
(e.g. <code>logpb.LogEntry</code>), but with any message type, one needs some kind of
reflection. The previous example used a function to redact IP addresses. To work
with any type of message, it could have been defined as <code>func redactIP(proto.Message) proto.Message { … }</code>.</p>
<p>Many years ago, your only option to implement a function like <code>redactIP</code> was to
reach for <a href="https://go.dev/blog/laws-of-reflection">Go&rsquo;s <code>reflect</code> package</a>,
which resulted in very tight coupling: you had only the generator output and had
to reverse-engineer what the input protobuf message definition might have looked
like. The <a href="https://go.dev/blog/protobuf-apiv2"><code>google.golang.org/protobuf</code> module
release</a> (from March 2020) introduced
<a href="https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect">Protobuf
reflection</a>,
which should always be preferred: Go&rsquo;s <code>reflect</code> package traverses the data
structure&rsquo;s representation, which should be an implementation detail. Protobuf
reflection traverses the logical tree of protocol messages without regard to its
representation.</p>
<p>Unfortunately, merely <em>providing</em> protobuf reflection is not sufficient and
still leaves some sharp edges exposed: In some cases, users might accidentally
use Go reflection instead of protobuf reflection.</p>
<p>For example, encoding a protobuf message with the <code>encoding/json</code> package (which
uses Go reflection) was technically possible, but the result is not <a href="https://protobuf.dev/programming-guides/proto3/#json">canonical
Protobuf JSON
encoding</a>. Use the
<a href="https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson"><code>protojson</code></a>
package instead.</p>
<p>The new Opaque API prevents this problem because the message struct fields are
hidden: accidental usage of Go reflection will see an empty message. This is
clear enough to steer developers towards protobuf reflection.</p>
<h3 id="idealmemory">Motivation: Making the ideal memory layout possible</h3>
<p>The benchmark results from the <a href="#lessmemory">More Efficient Memory
Representation</a> section have already shown that protobuf
performance heavily depends on the specific usage: How are the messages defined?
Which fields are set?</p>
<p>To keep Go Protobuf as fast as possible for <em>everyone</em>, we cannot implement
optimizations that help only one program, but hurt the performance of other
programs.</p>
<p>The Go compiler used to be in a similar situation, up until <a href="https://go.dev/blog/go1.20">Go 1.20 introduced
Profile-Guided Optimization (PGO)</a>. By recording the
production behavior (through <a href="https://go.dev/blog/pprof">profiling</a>) and feeding
that profile back to the compiler, we allow the compiler to make better
trade-offs <em>for a specific program or workload</em>.</p>
<p>We think using profiles to optimize for specific workloads is a promising
approach for further Go Protobuf optimizations. The Opaque API makes those
possible: Program code uses accessors and does not need to be updated when the
memory representation changes, so we could, for example, move rarely set fields
into an overflow struct.</p>
<h2 id="migration">Migration</h2>
<p>You can migrate on your own schedule, or even not at all—the (existing) Open
Struct API will not be removed. But, if you’re not on the new Opaque API, you
won’t benefit from its improved performance, or future optimizations that target
it.</p>
<p>We recommend you select the Opaque API for new development. Protobuf Edition
2024 (see <a href="https://protobuf.dev/editions/overview/">Protobuf Editions Overview</a>
if you are not yet familiar) will make the Opaque API the default.</p>
<h3 id="hybridapi">The Hybrid API</h3>
<p>Aside from the Open Struct API and Opaque API, there is also the Hybrid API,
which keeps existing code working by keeping struct fields exported, but also
enabling migration to the Opaque API by adding the new accessor methods.</p>
<p>With the Hybrid API, the protobuf compiler will generate code on two API levels:
the <code>.pb.go</code> is on the Hybrid API, whereas the <code>_protoopaque.pb.go</code> version is
on the Opaque API and can be selected by building with the <code>protoopaque</code> build
tag.</p>
<h3 id="rewriting">Rewriting Code to the Opaque API</h3>
<p>See the <a href="https://protobuf.dev/reference/go/opaque-migration/">migration
guide</a>
for detailed instructions. The high-level steps are:</p>
<ol>
<li>Enable the Hybrid API.</li>
<li>Update existing code using the <code>open2opaque</code> migration tool.</li>
<li>Switch to the Opaque API.</li>
</ol>
<h3 id="publishing">Advice for published generated code: Use Hybrid API</h3>
<p>Small usages of protobuf can live entirely within the same repository, but
usually, <code>.proto</code> files are shared between different projects that are owned by
different teams. An obvious example is when different companies are involved: To
call Google APIs (with protobuf), use the <a href="https://github.com/googleapis/google-cloud-go">Google Cloud Client Libraries for
Go</a> from your project. Switching
the Cloud Client Libraries to the Opaque API is not an option, as that would be
a breaking API change, but switching to the Hybrid API is safe.</p>
<p>Our advice for such packages that publish generated code (<code>.pb.go</code> files) is to
switch to the Hybrid API please! Publish both the <code>.pb.go</code> and the
<code>_protoopaque.pb.go</code> files, please. The <code>protoopaque</code> version allows your
consumers to migrate on their own schedule.</p>
<h3 id="enablelazy">Enabling Lazy Decoding</h3>
<p>Lazy decoding is available (but not enabled) once you migrate to the Opaque API!
🎉</p>
<p>To enable: in your <code>.proto</code> file, annotate your message-typed fields with the
<code>[lazy = true]</code> annotation.</p>
<p>To opt out of lazy decoding (despite <code>.proto</code> annotations), the <a href="https://pkg.go.dev/google.golang.org/protobuf/runtime/protolazy"><code>protolazy</code>
package
documentation</a>
describes the available opt-outs, which affect either an individual Unmarshal
operation or the entire program.</p>
<h2 id="nextsteps">Next Steps</h2>
<p>By using the open2opaque tool in an automated fashion over the last few years,
we have converted the vast majority of Google’s <code>.proto</code> files and Go code to
the Opaque API. We continuously improved the Opaque API implementation as we
moved more and more production workloads to it.</p>
<p>Therefore, we expect you should not encounter problems when trying the Opaque
API. In case you do encounter any issues after all, please <a href="https://github.com/golang/protobuf/issues/">let us know on the
Go Protobuf issue tracker</a>.</p>
<p>Reference documentation for Go Protobuf can be found on <a href="https://protobuf.dev/reference/go/">protobuf.dev → Go
Reference</a>.</p>


guid: bf157c8c1b784174e81dc1f89d60696f
title: Drawbacks of Moving to the Edge
author: Matt Rickard
url: https://mattrickard.com/drawbacks-of-moving-to-the-edge
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>Edge runtimes are often lauded as a fix to all latency concerns. But sometimes, moving to the edge can increase latency.</p>
<p>The problem: databases are still regional. If you move your application logic closer to the user via edge functions in multiple regions, this most likely increases the distance between your application and your database. Since the latter is often more chatty (more data sent back and forth between the application and database than the user and the application), this usually increases latency.</p>
<p><strong>Could you make data multi-regional?</strong> Sort of. There’s so work being done to bring the database to the edge (<a href="/sqlite-renaissance">see distributed SQLite</a>), but now with stateful data at the edge, you have a complicated distributed systems problem.</p>
<p><strong>Smarter caching?</strong> There’s also some work being done in application frameworks to do smarter caching (e.g., stale-while-revalidate) so that users get fast responses for most of the application while new data is rehydrated.</p>


guid: e21d67bef257013c1fc131c3e995ef75
title: Razor and Blades Model
author: Matt Rickard
url: https://mattrickard.com/razor-and-blades-model
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>The profit margin on Keurig machines is very low and sometimes even negative. On the other hand, the K-cup coffee pods have much higher profit margins.</p>
<p>The business model: sell one item at break-even or for free to increase the sales of the complementary good. This is the “razor and blades” model. (Despite being named after the safety razor industry, early companies like Gillette didn’t initially follow this model).</p>
<p>This model works especially well when there are <a href="/the-dynamics-of-switching-costs">switching costs or vendor-lock in</a>. If there are no switching costs, other providers can come in and compete margins away from the complementary good. When the K-cup patent expired in 2012, prices came down when competitors started producing compatible pods.</p>
<p>Or when a producer owns a monopoly on the complementary good. John D. Rockefeller and Standard Oil gave away eight million kerosene lamps. Demand for kerosene (conveniently sold by Standard Oil) skyrocketed.</p>
<p>Some other examples of the razor and blades model:</p>
<ul>
<li>Kindle e-reader / digital books.</li>
<li>Video game console / video games</li>
<li>Mobile phone / cellular data plan</li>
<li>Electric toothbrush / replacement brush heads</li>
<li>Printers / ink cartridges</li>
<li>E-cigarettes / e-cigarette pods</li>
</ul>


guid: 2149f91f7dabaa67cca42e77aedcf192
title: The Unreasonable Effectiveness of Monte Carlo
author: Matt Rickard
url: https://mattrickard.com/the-unreasonable-effectiveness-of-monte-carlo
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>Monte Carlo methods are used in almost every branch of science: to evaluate risk in finance, to generate realistic lighting and shadows in 3D graphics, to do reinforcement learning, to forecast weather, and to solve complex game theory games.</p>
<p>There are many types of Monte Carlo Methods, but they all follow a general pattern — using random sampling to model complex systems.</p>
<p><strong>A simple example:</strong> Imagine a complex shape you want to know the area of.</p>
<ol>
<li>Place the shape on a dartboard.</li>
<li>Randomly throw darts at the dartboard.</li>
<li>Count the number of darts that are inside the shape and outside.</li>
<li>The estimated area of the shape is = (number of darts in shape / number of darts outside of shape) * the area of the dartboard.</li>
</ol>
<p>(This is computing a definite integral numerically with a method that doesn’t depend on the dimensions! You can even easily estimate the error given the number of samples).</p>
<p><strong>Monte Carlo Tree Search (MCTS).</strong> Or use it to play a game like Blackjack (Chess, Go, Scrabble, and many other turn-based games) with Monte Carlo Tree Search. AlphaGo and its predecessors (AlphaGo Zero and AlphaZero) used versions of Monte Carlo Tree Search with reinforcement learning and deep learning.</p>
<p>The idea is fairly simple — add a policy (i.e., a strategy to follow) to the random sampling process. You might start with a simple one (random or stay with a hand under 18). For every move in a game, add that to a tree that describes the game. For Blackjack, that might be a series of hits or stays. When a game is won or lost, go back and update all of the nodes in the tree for that game (the “back propagation”).</p>
<p>After many games, you have a tree of expected utility for each move — that means you can sample the next move much more effectively. The value says something like — “given this current hand and set of actions, I won X% of the time”. You can get more advanced with the reward and update function — for example, you might discount wins that take many turns and prioritize quicker wins.</p>


guid: 93482a259760ff5774be879cc5300d32
title: Standard Causes of Human Misjudgment (Munger)
author: Matt Rickard
url: https://mattrickard.com/standard-causes-of-human-misjudgment-munger
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>In 1995, Charlie Munger gave a speech at Harvard on <a href="https://www.youtube.com/watch?v=Jv7sLrON7QY"><em>The Psychology of Human Misjudgment</em></a><em>.</em> It was filled with the research he had done later in life on human psychology, matched with real-life examples that he had observed in his work. The result was a succinct list of the top cognitive biases grounded in real-life experiences. I’ve summarized the biases here, but it’s worth giving the entire speech a listen to hear the stories behind each. I’ve tried to keep Charlie’s language and numbering when possible.</p>
<ol>
<li><strong>Underestimation of Incentives:</strong> Despite understanding the significant influence of incentives (reinforcement in psychology and incentives in economics), there's a tendency to consistently underestimate their power.</li>
<li><strong>Psychological Denial:</strong> This is the refusal to accept reality because it is too painful or difficult to bear.</li>
<li><strong>Incentive-Cause Bias:</strong> This occurs when personal incentives or those of a trusted advisor create a conflict of interest, leading to biased decisions.</li>
<li><strong>Bias from Consistency and Commitment:</strong> This involves a strong tendency to stick to pre-existing beliefs or commitments, even in the face of contradictory evidence.</li>
<li><strong>Bias from Pavlovian Association:</strong> This bias refers to the error of basing decisions on past associations or correlations without considering their current relevance or accuracy.</li>
<li><strong>Bias from Reciprocation Tendency:</strong> This bias involves a natural inclination to reciprocate actions and behaviors, including conforming to others' expectations, especially when one is experiencing success or is 'on a roll.'</li>
<li><strong>Bias from Over-Influence by Social Proof:</strong> This bias refers to the heavy reliance on the actions or decisions of others, especially in situations of uncertainty or stress.</li>
<li><strong>Bias from Favoring Elegance over Practicality in Theory:</strong> This bias involves a preference for theories or explanations that are mathematically elegant or intellectually satisfying, even if they are less accurate in practical terms. “Better to be roughly right than precisely wrong” — Keynes.</li>
<li><strong>Bias from Contrast-Induced Distortions:</strong> This bias refers to the way our perceptions, sensations, and cognition can be significantly altered by contrasts.</li>
<li><strong>Bias from Over-Influence by Authority:</strong> This bias involves the tendency to conform to instructions or opinions provided by an authority figure, even when these instructions conflict with one's own moral judgment or common sense.</li>
<li><strong>Bias from Deprival Super Reaction Syndrome:</strong> This bias is characterized by an intense reaction to losing or the threat of losing something, especially something that one perceives as almost possessed but never fully owned.</li>
<li><strong>Bias from Deprival Super Reaction Syndrome:</strong> This bias is characterized by an intense reaction to losing or the threat of losing something, especially something that one perceives as almost possessed but never fully owned.</li>
<li><strong>Bias from Envy/Jealousy:</strong> This bias stems from feelings of envy or jealousy towards others.</li>
<li><strong>Bias from Chemical Dependency:</strong> This bias relates to the cognitive and behavioral changes that result from chemical dependency, such as addiction to drugs or alcohol.</li>
<li><strong>Bias from Gambling Compulsion:</strong> This bias refers to the compulsive urge to gamble, driven by the psychological principle of variable reinforcement.</li>
<li><strong>Bias from Liking Distortion:</strong> This bias involves a preference for things that are familiar or similar to oneself, including one's own ideas, kind, and identity.</li>
<li><strong>Bias from Disliking Distortion:</strong> This is the opposite of liking distortion, where there's a tendency to reject or not learn from sources that are disliked.</li>
<li><strong>Bias from the Non-Mathematical Nature of the Human Brain in Probability Assessment:</strong> This bias refers to the human brain's tendency to rely on crude heuristics and be easily misled by contrasts when dealing with probabilities, rather than using precise mathematical approaches.</li>
<li><strong>Bias from Over-Influence by Extra Vivid Evidence:</strong> This bias describes the tendency to give disproportionate weight to particularly vivid or emotionally striking information when making decisions.</li>
<li><strong>Stress-induced mental changes, small and large, temporary and permanent.</strong></li>
<li><strong>Mental Confusion from Poorly Structured Information and Inadequate Explanations:</strong> This bias involves difficulties in understanding or decision-making due to information that is not well-organized or lacks a coherent theoretical framework.</li>
</ol>


guid: b5f92453f96d30f537c4cd759f63eb90
title: Discord and AI GTM
author: Matt Rickard
url: https://mattrickard.com/discord-and-ai-gtm
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>Midjourney is the largest discord server, with 16.5 million total users. It accounts for 13% of total Discord invites. Midjourney launched in March 2022 and doesn’t have a web application. Many other AI apps (Leonardo, Pika, Suno, And AI Hub) are on Discord (or even Discord-only).</p>
<p>Why is Discord such a good GTM for AI applications?</p>
<ul>
<li><strong>Text interface.</strong> Most users are just generating images, videos, and audio in these Discord servers. Prompts are easily expressible in simple text commands. It’s why we’ve seen image generation strategies like Midjourney (all-in-one) flourish in Discord while more raw diffusion models haven’t grown as quickly (e.g., Stable Diffusion with many configurable parameters).</li>
<li><strong>Virality.</strong> Prompt engineering models is difficult and more art than science (today). Users can see generations by other users and collectively see what’s working and what isn’t. This means that these communities often have the most advanced prompts and best images.</li>
<li><strong>Low friction.</strong> Go to where your users already are. Most developers have Discord now. One fewer application to sign up for.</li>
<li><strong>Free hosting.</strong> Discord pays for the image hosting and bandwidth. At Midjourney scale, this is not negligible.</li>
</ul>
<p>But Discord has it’s risks as a platform to build on.</p>
<ul>
<li><strong>Platform risk.</strong> Discord could (easily?) build its own Midjourney-type application into the platform. Using all of the prompt-image pairs (along with reactions as a RLHF), it could probably distill a much better model from Midjourney (questionably legal but technically easy). This reminds me of the Zynga / Facebook relationship. <a href="/growth-hacking-platforms">Zynga accounted for 19% of Facebook’s revenue at one point.</a> Facebook reduced Zynga’s API access and launched its own gaming platform.</li>
<li><strong>Multi-modal.</strong> How does multi-modal fit into the Discord text-first interface? Sure there are images and audio that can be uploaded via the interface, <a href="/multi-modal-ai-is-a-ux-problem">but it’s hard to image the UI that a multi-modal AI will need in the future.</a></li>
</ul>


guid: 8c321aca02314bd1fd41009cbd5ada31
title: Data Quality in LLMs
author: Matt Rickard
url: https://mattrickard.com/data-quality-in-llms
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>Good data is the difference between Mistral’s LLMs and Llama, which share similar architectures but different datasets.</p>
<p>To train LLMs, you need data that is:</p>
<ol>
<li><strong>Large</strong> — Sufficiently large LMs require trillions of tokens.</li>
<li><strong>Clean</strong> — Noisy data reduces performance.</li>
<li><strong>Diverse</strong> — Data should come from different sources and different knowledge bases.</li>
</ol>
<p><em>What does clean data look like?</em></p>
<p>You can de-duplicate data with simple heuristics. The most basic would be removing any exact duplicates at the document, paragraph, or line level. More advanced versions might look at the data semantically, figuring out what data should be omitted because it’s better represented with higher quality data.</p>
<p>The other dimension of clean data is converting various file types to <a href="/good-enough-abstractions">something easily consumed by the LLM, usually markdown</a>. That’s why we’ve seen projects like <a href="https://github.com/facebookresearch/nougat">nougat</a> and <a href="https://github.com/clovaai/donut">donut</a> convert PDFs, books, and LaTeX to better formats for LLMs. There’s a lot of training data that’s still stuck in PDFs and human-readable but not so easily machine-readable data.</p>
<p><em>Where does diverse data come from?</em></p>
<p>The surprising result of the success of the GPTs is that web text from the Internet is probably one of the most diverse datasets out there. It contains usage and data that aren’t found in many other data corpora. That’s why models tend to perform so much better when they’re given more data from the web.</p>


guid: eb2102f1d65a9c3bdfa48d26e92d4186
title: McNamara Fallacy
author: Matt Rickard
url: https://mattrickard.com/mcnamara-fallacy
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>The McNamara Fallacy is named after Robert McNamara, the US Secretary of Defense during the Vietnam War. The fallacy describes making decisions using only quantitative metrics and ignoring anything else.</p>
<p>The fallacy usually follows the same four steps.</p>
<ol>
<li>Measure what can easily be measured.</li>
<li>Dismiss what can’t be measured easily.</li>
<li>Presume what can’t be measured easily isn’t important.</li>
<li>Extrapolate and conclude that what can’t be measured doesn’t exist.</li>
</ol>
<p>You can find the McNamara Fallacy in all types of disciplines. The emphasis on standardized tests in education (at the expense of less quantifiable qualities and learning). Or when the success of treatments in medicine is based only on easy to measure outcomes (not quality of life, mental health, or overall well-being). Or optimizing for short-term financial metrics at the expense of brand reputation, employee satisfaction, or other intangibles.</p>


guid: 8758d57dd36ad484b296760e964a3138
title: ChatGPT After One Year
author: Matt Rickard
url: https://mattrickard.com/chatgpt-after-one-year
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>ChatGPT was released on November 30th 2022. What has changed since then?</p>
<ul>
<li><strong>Hundreds of open-source models.</strong> Varying sized models from small to very large. Many are chat-tuned similar to ChatGPT.</li>
<li><strong>Distilled models from ChatGPT.</strong> Academics and competitors both used data from ChatGPT conversations to train or fine-tune their own models.</li>
<li><strong>Competition.</strong> Microsoft launched Bing Chat. Google launched Bard. Poe, Pi, Perplexity. Claude by Anthropic. Not to mention self-hosted open-source chat UIs and other wrappers. There’s no shortage of competition (although ChatGPT still is the most popular).</li>
<li><strong>RAG is hard.</strong> “Browse with Bing” and Bing Chat launched but hallucinations are still an issue. Browsing the internet doesn’t seem like the catch-all</li>
<li><strong>Not every launch increased performance across the board.</strong> Every new iteration of ChatGPT launched changed the way the model behaved. Many queries got better. Some got worse. Google has always had this problem as well, but applications aren’t build on Google.</li>
<li><strong>A consumer subscription model.</strong> ChatGPT Plus was released in February 2023. The consumer model maybe competes with the developer and enterprise products (why not just use the API?).</li>
<li><strong>Multi-modal.</strong> ChatGPT started to accept images and files in the chat. DALL-E and the vision API became integrated into the chat window. There are open-source models that are multi-modal, but so far no experience is as sleek as OpenAI’s.</li>
<li><a href="/chatgpt-plugins-dont-have-pmf"><strong>Plugins launched but never found product-market fit</strong></a><strong>.</strong> Plugins launched but didn’t become the <a href="/necessary-conditions-for-an-app-store-monopoly">App Store</a> that OpenAI hoped. Custom GPTs seem to be the next strategy for extensibility, although they won’t launch until next year.</li>
<li><strong>Code Interpreter is getting better.</strong> Agents and tool-use is still hard for LLMs. But it’s getting better and becoming more useful. Files can now be added directly to the UI to chat with.</li>
</ul>


guid: 3e18ce4e909b25c798151e08c5c45f77
title: Fairchildren
author: Matt Rickard
url: https://mattrickard.com/fairchildren
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>In 1956, William Shockley, Stanford professor and winner of the Nobel Prize in Physics for his work on semiconductors, recruited a team of young Ph.D. graduates to product a new company. The company would be called Shockley Semiconductor.</p>
<p>But Shockley was a terrible manager, and the students left to form their own company the next year, Fairchild Semiconductor. They would be later known as the “traitorous eight”.</p>
<p>The founders of Fairchild Semiconductor were: Gordon Moore, C. Sheldon Roberts, Eugene Kleiner, Robert Noyce, Victor Grinich, Julius Blank, Jean Hoerni, and Jay Last.</p>
<p>Fairchild Semiconductor became the proto-company of Silicon Valley. Many major technology companies can somehow trace their founding or story to Fairchild.</p>
<p><strong>Intel</strong> - Founded by Robert Noyce and Gordon Moore, both former employees of Fairchild Semiconductor.</p>
<p><strong>AMD (Advanced Micro Devices)</strong> - Founded by Jerry Sanders, another Fairchild alumnus.</p>
<p><strong>Kleiner Perkins</strong> - A venture capital firm co-founded by Eugene Kleiner, a former Fairchild employee.</p>
<p><strong>Sequoia Capital—</strong> Don Valentine worked at Fairchild Semiconductor for seven years before moving to National Semiconductor (another Fairchild). Then, he started Sequoia Capital.</p>
<p>Other companies founded by Fairchild employees: SanDisk, National Semiconductor, Altera, LSI Logic, Amelco, Applied Materials, and more.</p>


guid: bf20cc6610e5ae5e8732c3999575d312
title: Pseudonyms in American History
author: Matt Rickard
url: https://mattrickard.com/pseudonyms-in-american-history
feedurl: https://matt-rickard.com/rss
content_mime_type: text/html
content:
<p>Debates around the ratification of the Constitution and the early formation of the United States happened through pseudonymous authors. They often used names borrowed from Greek or Roman History.</p>
<p>Why?</p>
<ul>
<li>Plausibly some protection against retaliation. However, most pseudonymous writing was quickly attributed to authors.</li>
<li>Power in names. The names weren’t chosen at random. Often, they called back to famous Romans who took part in the formation of the Roman Republic. Or others who were known for their virtue or principles.</li>
</ul>
<p>Alexander Hamilton might have written under the most pseudonyms (at least five). Benjamin Franklin used at least three. Here’s a list of some of the more popular ones around the time of the American Revolution.</p>
<p><strong>Phocion</strong> (Alexander Hamilton) — Essays defending the Jay Treaty with Great Britain. Phocion was an Athenian statesman known for his integrity and opposition to demagoguery.</p>
<p><strong>Columbus</strong> (Alexander Hamilton) — Defending the Continental Congress and criticizing British policies.</p>
<p><strong>Publius</strong> (Alexander Hamilton, James Madison, John Jay) — The authors of the Federalist Papers, which were a series of essays advocating for the ratification of the Constitution. Individual authorship wasn’t released until Hamilton’s death, and even then historians are still trying to match authors to text. It’s hypothesized that Hamilton wrote 51 essays, Madison 29, and Jay 5. Publius Valerius Poplicola was a Roman consul known for his role in founding the Roman Republic.</p>
<p><strong>Historicus</strong> (Alexander Hamilton) — Essays on various topics related to the Constitution and federalism.</p>
<p><strong>Pacificus</strong> (Alexander Hamilton) — Used to defend President George Washington's Neutrality Proclamation of 1793 (declared the U.S. neutral in the conflict between France and Great Britain). “Making peace” in Latin.</p>
<p><strong>Helvidius</strong> (James Madison) — Written in response to Pacificus (Hamilton), these essays defended the constitutional authority of Congress in foreign affairs. Helvidius Priscus was a Roman senator known for his defense of republicanism and freedom of speech.</p>
<p><strong>Americanus</strong> (John Jay, John Stevens, Jr.) — Federalists essays.</p>
<p><strong>Candidus</strong> (Benjamin Franklin) — Writings advocating for various causes, including opposition to oppressive British policies.</p>
<p><a href="/silence-dogood-and-the-ben-franklin-effect"><strong>Silence Dogood</strong></a> (Benjamin Franklin) — A fictitious widow created by Franklin to offer social commentary.</p>
<p><strong>Richard Saunders “Poor Richard”</strong> (Benjamin Franklin) — Used to publish <em>Poor Richard’s Almanack</em>. The name comes from a popular London almanac, <em>Rider’s British Merlin</em>.</p>
<p><strong>“Common Sense” —</strong> Thomas Paine’s pamphlet advocating for American independence was initially published anonymously.</p>
<p><a href="/cincinnatus"><strong>Cincinnatus</strong></a> <strong>(Arthur Lee) —</strong> Anti-federalist papers.</p>
<p><strong>A Farmer</strong> <strong>(John Dickinson)</strong> — Essays titled "Letters from a Farmer in Pennsylvania," which argued against the Townshend Acts imposed by the British.</p>
<p><strong>Cato</strong> (George Clinton) — Anti-federalist essays around the time of the ratification of the Constitution. Attributed to George Clinton, but not confirmed. Cato the Younger was a Roman statesman known for his staunch republicanism and opposition to Julius Caesar.</p>
<p><strong>Brutus</strong> (Robert Yates) — An ally of George Clinton’s who wrote more anti-federalist essays. Marcus Junius Brutus was a Roman senator famous for his role in the assassination of Julius Caesar, symbolizing resistance to tyranny.</p>
<p><strong>Centinel</strong> (Samuel Bryan) — A series of anti-federalist essays critical of the proposed U.S. Constitution's centralizing tendencies.</p>
<p><strong>Americanus</strong> (John Stevens, Jr.) — Essays written to support the Federalist cause and the ratification of the U.S. Constitution.</p>
<p><strong>Poplicola</strong> (John Adams) — Essays defending the British constitution and criticizing the Stamp Act. The same Publius Valerius Poplicola used by Hamilton.</p>
<p><strong>Novanglus</strong> (John Adams) — A series of essays written in response to Massachusettensis, defending colonial rights. Latinization of “New Englander”.</p>
<p><strong>A Citizen of New York</strong> (Martin Van Buren) — political essays.</p>


guid: yt:video:ii8kiBt3cVw
title: Odin Compiler Development ~ Tilde Backend 2023-07-18
author: gingerBill
url: https://www.youtube.com/watch?v=ii8kiBt3cVw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUSck1dOH7VKmG4lRW7tZXg
enclosure_url: https://www.youtube.com/v/ii8kiBt3cVw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Broadcasted live on Twitch -- Watch live at https://www.twitch.tv/ginger_bill

SSA Bibliography: https://www.dcs.gla.ac.uk/~jsinger/ssa.html
Cliff Click Paper: https://www.oracle.com/technetwork/java/javase/tech/c2-ir95-150110.pdf


guid: yt:video:XB5xuAhrkWE
title: The Greenwich Meridian is in the wrong place
author: Stand-up Maths
url: https://www.youtube.com/watch?v=XB5xuAhrkWE
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/XB5xuAhrkWE?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Pre-order Love Triangle anywhere, register for the sweepstakes here: https://sites.prh.com/love-triangle-sweepstakes

Details on where you can pre-order/buy Love Triangle: https://bit.ly/3wCTesR

Or if you just want it from Amazon, this is my affiliate link: https://amzn.to/4fy30Ph

For people in Europe, signed UK copies are still available on Maths Gear: https://mathsgear.co.uk/products/love-triangle-by-matt-parker-signed

Huge thanks to Steve Mould for joining me in this video! Check out Steve's channel, I assume he can use some extra subscribers: https://www.youtube.com/stevemould

Thanks to the Royal Observatory, Greenwich for letting us come in to see all the lines and their respective telescopes. You should visit! It's in London. https://www.rmg.co.uk/royal-observatory

Much appreciation to my Patreon supporters. They keep me on the correct line. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Steve Mould performed by Steve Mould
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:SYBRxqEE4XQ
title: Search for the mythological Klein-ing Frame
author: Stand-up Maths
url: https://www.youtube.com/watch?v=SYBRxqEE4XQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/SYBRxqEE4XQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Find out more about Jane Street's internships in Hong Kong and opportunities around the world! https://jane-st.co/hkginternship-sum

Visit the Klein-ing Frame and the rest of the park yourself: http://www.infopia.net/create/index.html

This is the site and map I originally found.
Site: https://polyhedra.cocolog-nifty.com/blog/2019/04/post-87185f.html
Map: http://www.infopia.net/create/images/route1.pdf

Check out the original Tweet: https://x.com/MathematicsUCL/status/1358532581113946114

Huge thanks to David Brooks for being our guide. More on their physics work at JAXA and elsewhere here: https://davidbrooks.info/about/

If you'd like to know more about ISAS/JAXA, their site is here: https://www.isas.jaxa.jp/en/
Anyone interested in Hinode can look at the MSSL website here: https://solarb.mssl.ucl.ac.uk/SolarB/

Huge thanks to my Patreon supporters. Without them I would be orientation-reversed. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming by Alex Genn-Bash
Editing by Gus Melton
Written, performed and additional filming by Matt Parker
Local translation services by Dave Brooks
Attending a conference in Japan to justify the trip by Lucie Green
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/
US book: https://www.penguinrandomhouse.com/books/610964/humble-pi-by-matt-parker/
UK book: https://mathsgear.co.uk/collections/books/products/humble-pi-signed-paperback


guid: yt:video:XZy3rXr2yeM
title: The search for the biggest shape in the universe.
author: Stand-up Maths
url: https://www.youtube.com/watch?v=XZy3rXr2yeM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/XZy3rXr2yeM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Love Triangle sweepstakes are open until Monday August 19th: https://sites.prh.com/love-triangle-sweepstakes

Details on where you can pre-order/buy Love Triangle: https://bit.ly/3wCTesR 
Or if you just want it from Amazon, this is my affiliate link: https://amzn.to/4fy30Ph 

For people in Europe, signed UK copies are still available on Maths Gear: https://mathsgear.co.uk/products/love-triangle-by-matt-parker-signed 

“Search For Largest Polyhedra” by Donald Grace
https://www.ams.org/journals/mcom/1963-17-082/S0025-5718-63-99183-X/S0025-5718-63-99183-X.pdf

Thanks to Bill Hedges at Cosmic Films Studio in Nebraska, USA for having us to film our sci-fi adventure. Check out Bill’s Cosmic Cat series: https://www.youtube.com/@williamhedges1519

Thanks to Laura Taalman for 3D printing the fantastic shapes for me. She's a Professor of Mathematics at James Madison University. https://mathgrrl.com/

Thanks to Roger Antonsen, for testing the local maxima of the Grace shape for this video. Roger sadly passed away earlier this year. His department at the University of Oslo have published a memorial page to celebrate him: https://www.mn.uio.no/ifi/personer/minneside.html

Geogebra model of the Grace's Shape made by Sam Hartburn.

Much appreciation to Donald's children who talked to me about late nights spent with their father watching a computer crunch away at some math.

Huge thanks to my Patreon supporters. I could maximise the occupancy of a unit sphere with my gratitude. https://www.patreon.com/standupmaths

CORRECTIONS
- 00:23 I say "August 22" which is wrong: this Tuesday is August 20. Please don't tell my publishers I got that wrong.
- At 16:50 I say "eight times" which is completely wrong and not part of the formula. No idea what was going on there. The onscreen value (and everything else I say) is correct.
- Let me know if you spot anything else! 

Filming and editing by Alex Genn-Bash
Additional footage by Bill Hedges
Written and performed by Matt Parker
Voiceover by Gemma Arrowsmith
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
On-set entertainment by Cosmic Cat (and kittens)

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:AHP1T8fTxpQ
title: The Bingo Paradox: 3× more likely to win
author: Stand-up Maths
url: https://www.youtube.com/watch?v=AHP1T8fTxpQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/AHP1T8fTxpQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Details on where you can buy Love Triangle in the USA: https://bit.ly/3wCTesR 

Or if you just want it from Amazon, this is my affiliate link: https://amzn.to/4fy30Ph 

For people in Europe, signed UK copies are still available on Maths Gear: https://mathsgear.co.uk/products/love-triangle-by-matt-parker-signed

The box set you should not buy:
https://achievefulfilment.onwarehouse.app/preorders/new?campaign_id=ymgvcjy

Paul Catherall shop:
https://www.paulcatherall.com/shop/

And now for some actual links that pertain to the video itself.

The Bingo Paradox by Arthur Benjamin, Joseph Kisenwether & Ben Weiss
https://www.tandfonline.com/doi/abs/10.4169/mathhorizons.25.1.18
Also here: http://digitaleditions.walsworthprintgroup.com/publication/?i=432359&article_id=2856994&view=articleBrowser

10,000 Stand-up Maths bingo cards: https://www.dropbox.com/scl/fo/t8l5pl23axozpjidbdun7/AFzNqCra3HfowHTtSuluHO0?rlkey=b4m5vp13b4fdug6521ijb8unw&dl=0

10,000 Love Triangle bingo cards: https://www.dropbox.com/scl/fo/zy93kfqqy2rb4n4wstgu4/AM0E6heZnvFW6cNFek7xG7U?rlkey=nkc9d71dw4bp4r01dp8dhos6p&dl=0

I heard a rumour you should listen to the podcast A Problem Squared. https://open.spotify.com/show/7Hp5QDk9PsWyEXtcsDz34a?si=9d0a481401de443a

Huge thanks to my Patreon supporters. They took very little convincing to make fun of me via the medium of bingo card suggestions. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Additional performance by Skylab the Dog
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
Dice on loan from the Bec Hill collection

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/
US book: https://www.penguinrandomhouse.com/books/610964/humble-pi-by-matt-parker/
UK book: https://mathsgear.co.uk/collections/books/products/humble-pi-signed-paperback


guid: yt:video:QYUE696k6GY
title: We shot a YouTube video about film formats on 35mm film
author: Stand-up Maths
url: https://www.youtube.com/watch?v=QYUE696k6GY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/QYUE696k6GY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
If you'd like a piece of the film: support me on Patreon. https://www.patreon.com/standupmaths

Then sign up to get the physical film here: https://forms.gle/eNc46SgJW9bn3RaF6

If you'd like to watch every last frame we shot, the complete scan of every roll of film is on my second channel. https://youtu.be/99ru8jtD7-4

Comment below if you think there is a preexisting video which would beat me as the first 35mm filmed-as-a-YouTube-video video.

Huge thanks to Keslow Camera for letting us use their fantastic film cameras. They hire all sorts of great stuff: https://www.keslowcamera.com/

Much appreciation to Truman Hanks who suggested the video idea, organised the film, shot the video and did the edit. Check out his film-loading and cinematography work: https://www.trumanhanks.com/

Thanks to Bec Hill for helping out with the filming on the day. All the props were lovingly hand-made by Bec using stationery we found around Sam Kieffer's place.

My podcast with Bec: https://podcasters.spotify.com/pod/show/a-problem-squared
Bec's podcast with Sam, which they should have been working on instead of helping me make giant models of film: https://podcasters.spotify.com/pod/show/enemy-in-paris

Thanks again to Dan Ming for setting us up with Keslow. Read about their work here in ICG Magazine. https://issuu.com/icgmagazine/docs/may2023/16

Development was by FotoKem and the digital scan of the film was done by the lovely The Negative Space. https://thenegative.space/

Huge thanks to my Patreon supporters. They keep my reels turning. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming and editing by Truman Hanks
Sound mix by Peter Doggart
Written and performed by Matt Parker
Props by Bec Hill
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:Abmm85aqeWk
title: Are accurate election predictions luck or skill?
author: Stand-up Maths
url: https://www.youtube.com/watch?v=Abmm85aqeWk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/Abmm85aqeWk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Go to https://ground.news/standup for a data-driven, objective way to stay fully informed on the issues most important to you. Save 40% on the Ground News unlimited access Vantage plan with my link.

Thanks to Jop Schaap for analysing how lucky I was. See their report here: https://www.dropbox.com/scl/fi/yrzp0z3r2u4dgistmtor1/Lucky_predictions_Jop_Schaap.pdf?rlkey=c0ctkocele9sso7kh46y73kcp&dl=0

If you'd like to see my spreadsheet, here it is. The percentages and values were all generated by some terrible python code I hand-wrote myself. https://www.dropbox.com/scl/fi/e6wfyb9382gr6ihnvyp7z/Lucky_predictions_Matt-spreadsheet.xlsx?rlkey=95lj0l1c59meo1yrxq0hxjgol&dl=0

Thanks to Evan Harris for chatting about election stats with me and kindly recording a video. Here's the big table of data they made: https://www.dropbox.com/scl/fi/3ahu3g5gouaseb7ch7f0s/Mid-Sussex-Local-Election-Results.docx?rlkey=g22ko1y5h8sb414vrfgfpvf6t&dl=0

Ongoing thanks to Count Binface, Tom Wilson and Dave Rowntree who have helped hugely with this video series.

Part 01: https://youtu.be/zDLxgEquxA0
Part 02: https://youtu.be/K-hdJIWsK3A

Massive thanks to my Patreon supporters. I'm definitely lucky to have you all. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming by Matt Parker
Editing by Gus Melton
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Opening titles by Alex Genn-Bash
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:ga9Qk38FaHM
title: The unexpected probability result confusing everyone
author: Stand-up Maths
url: https://www.youtube.com/watch?v=ga9Qk38FaHM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/ga9Qk38FaHM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Secure your privacy with Surfshark! Enter coupon code standupmaths for an extra 4 months free at https://surfshark.com/standupmaths

Thanks to Dylan from Seattle for sending this amazing maths fact to me. You can see an archive of their ChatGPT conversation here: https://chatgpt.com/share/00ed003b-8be6-4756-92b3-de91454ab3f2

Thanks to Grant from 3blue1brown for putting actual work aside and talking probabilities with me on a long train journey. You see see a longer version of this animations here: https://youtube.com/3blue1brown

This was my dice video from a few years back, "The unexpected logic behind rolling multiple dice and picking the highest." https://www.youtube.com/watch?v=X_DdGRjtwAo

Satisfy your D36 and all your other dice needs over at Maths Gear: https://mathsgear.co.uk/products/d36-dice

Also on the Dice Lab if you're USA based. https://www.mathartfun.com/d141518.html

Huge thanks to my Patreon supporters. They keep me in dice. So many dice. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 
- PS Never say die.

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
Throwing Dice at Matt: also by Alex Genn-Bash
Some dice on loan from the Bec Hill collection

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:b5nElEbbnfU
title: How can a jigsaw have two distinct solutions?
author: Stand-up Maths
url: https://www.youtube.com/watch?v=b5nElEbbnfU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/b5nElEbbnfU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Learn more about Jane Street’s internship opportunities: https://jane-st.co/SUM-internships

Check out Steve’s video: https://youtu.be/FMRi6pNAoag

This is Ryan’s Diffusion Illusions site: https://diffusionillusions.com

And here is the full “Diffusion Illusions: Hiding Images in Plain Sight” paper by Ryan Burgert, Xiang Li, Abe Leite, Kanchana Ranasinghe and Michael S. Ryoo. https://diffusionillusions.com/assets/diffusion_illusions.pdf

Download of the jigsaw: https://www.dropbox.com/scl/fi/rennmoqgzjdup5uof7qna/jigsaw_jumbled.pdf?rlkey=u4v18cwbvut672hqx895tqga0&dl=0

Here’s the layout of the different edge types:  https://www.dropbox.com/scl/fi/dvylpftby1uzlrmpdt1mp/matt-jigsaw-layout.pdf?rlkey=512hqdr9y9h5mxjonhxiwhsy4&dl=0

Huge thanks to my Patreon supporters. They provide all the valid solutions I need. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming by Alex Genn-Bash
Editing by Gus Melton
Written and performed by Matt Parker and Steve Mould
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
Dice on loan from the Bec Hill collection

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:zsyGRDrDfbI
title: New largest prime number found! See all 41,024,320 digits.
author: Stand-up Maths
url: https://www.youtube.com/watch?v=zsyGRDrDfbI
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/zsyGRDrDfbI?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
2^136,279,841 - 1 has 41,024,320 digits and is prime! Read all about the new largest prime number ever found: https://www.mersenne.org/primes/?press=M136279841

Huge thanks to Luke Durant, George Woltman and everyone at the Great Internet Mersenne Prime Search.

Get involve in the search for large primes! https://www.mersenne.org/

This is the breakdown of the maths methods used by the Great Internet Mersenne Prime Search: https://www.mersenne.org/various/math.php

Here are the details of the test completed on M52 (the 52nd Mersenne prime). https://www.mersenne.org/report_exponent/?exp_lo=136279841&full=1

The old computer photo was of Alice Betsy and Donald Gillies in front of the ILLIAC I computer which found three record-breaking primes in 1963. https://en.wikipedia.org/wiki/Donald_B._Gillies

In 2016 I printed the then-biggest prime: https://www.youtube.com/watch?v=tlpYjrbujG0
And I talked about the Lucas-Lehmer test to prove it is prime: https://www.youtube.com/watch?v=tlpYjrbujG0

This is my Pi By Hand video which Daniel B also features in. https://www.youtube.com/watch?v=LIg-6glbLkU

Yes, pieces of Skylab (spacecraft, not dog) are in Esperance, Western Australia. https://www.esperance.wa.gov.au/esperance-museum/skylab

Keep an eye on A Problem Squared to see why I was recording somewhere between Perth and Esperance. https://podcasters.spotify.com/pod/show/a-problem-squared

Huge thanks to my Patreon supporters. I bought Lucie and Steve pizza at Lucky Bay Brewing. Support me and I'll buy more beer for my family. Think of my family! https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming by Lucie Green
Timing and moral support by Steve Parker
Editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/

What's that? You want the first 1,000 and the last 1,000 digits? Ok then.

...


guid: yt:video:GyNbLtiAgj4
title: What do we know about Asteroid 314159 aka ‘Mattparker’?
author: Stand-up Maths
url: https://www.youtube.com/watch?v=GyNbLtiAgj4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/GyNbLtiAgj4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Order Love Triangle now and get a personalised gift tag! https://achievefulfilment.onwarehouse.app/preorders/new?campaign_id=wng5c4y

Or just get a copy with no gift tag. You'll receive it a bit faster. https://achievefulfilment.onwarehouse.app/preorders/new?campaign_id=yx6gcky

There is a small chance we still have limited-edition covers left. You can check here: https://achievefulfilment.onwarehouse.app/preorders/new?campaign_id=w7qzcxw

Thanks to everyone who bought the USA edition! You can still get copies here: https://www.penguinrandomhouse.com/books/672455/love-triangle-by-matt-parker/

I will send out the book marks soon! I didn't quite get them all done before the video was released.

Huge thanks to David Rankin (R&D Operations Engineer, Catalina Sky Survey, University of Arizona) for discovering Mattparker as well as taking the time to talk to me about it. David's channel: https://www.youtube.com/@rankinstudio

Details and data about Mattparker
https://minorplanetcenter.net/db_search/show_object?utf8=%E2%9C%93&object_id=314159
https://ssd.jpl.nasa.gov/tools/sbdb_lookup.html#/?sstr=314159
Search for "314159" on https://alcdef.org/

Here is the Numberphile video: https://www.youtube.com/watch?v=n9lKcs-h7fg&ab_channel=Numberphile

Huge thanks to Ilgmars Eglitis (Head of Baldone Observatory, Latvia) for running the extra analysis of Mattparker's light curve and found the approximate rotation period and shape.

"Light curve analysis of main belt asteroids 4747, 5255, 11411, 15433, 17866" https://www.degruyter.com/document/doi/10.1515/astro-2022-0227/html?lang=en

This paper contains a derivation of the absolute brightness to size equation.
https://mathscinotes.com/wp-content/uploads/2016/08/Jackpot.pdf

Asteroid belt diagram based on a NASA image from here: https://www.nasa.gov/image-article/picturing-our-solar-systems-asteroid-belt/

Cheers to my Patreon supporters for supplying so many great depictions of Mattparker. Support me on Patreon and you can join in with the next ridiculous thing I ask for help with. Also a christmas card. https://www.patreon.com/standupmaths

CORRECTIONS
- Yes, I said days instead of hours. But we fixed that with the text.
- Let me know if you spot anything else!

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:5vbk0TwkokM
title: How on Earth does ^.?$|^(..+?)\1+$ produce primes?
author: Stand-up Maths
url: https://www.youtube.com/watch?v=5vbk0TwkokM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/5vbk0TwkokM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Take your personal data back with Incogni! Use code standupmaths at the link below and get 60% off an annual plan: https://incogni.com/standupmaths

^.?$|^(..+?)\1+$

Props will be for sale here: https://www.ebay.co.uk/usr/standupmaths

Fantastic blog post by Illya Gerasymchuk. "Demystifying The Regular Expression That Checks If A Number Is Prime" https://illya.sh/the-codeumentary-blog/regular-expression-check-if-number-is-prime/

Thanks to everyone who has sent in history about this regex. Seems it was written ≥25 years ago by a Perl programmer named Abigail.

Cheers to viewer Dave Cross who found this earliest-known mention in a 2000 blog post: http://test.neilk.net/blog/2000/06/01/abigails-regex-to-test-for-prime-numbers/

Thanks to viewers Chris Lawrence and Jimmy Diep for suggesting the topic.

Huge thanks to my Patreon supporters. They keep me supplied with all the primes I need. https://www.patreon.com/standupmaths

CORRECTIONS
- Several people have corrected me that regex is zero indexed it’s just that \0 refers to the entire matched string.
- Mike Salisbury ands others have pointed out that the left-most column in the table of repeated wild cards shouldn't be included. Otherwise the length of the string could match a single prime length. 
- At 6:07 I say "Begins and end with an m" when I meant ends with an “s”. No one has corrected that mistake with more vigour than viewer Timur Sultanov.
- There is some concern about my pronunciation of rejex.
- Let me know if you spot anything else!

Filming, VFX and editing by Alex Genn-Bash
Written and performed by Matt Parker
Extra material by Sam Hartburn
Number yeeting by Lucie Green
Spooky lighting and producing by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:KXQ1ieFRr0o
title: Can the "Red Mirage" and "Blue Shift" be explained with math? ELECTION 2024
author: Stand-up Maths
url: https://www.youtube.com/watch?v=KXQ1ieFRr0o
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/KXQ1ieFRr0o?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Here is the full MIT Election Data and Science Lab report: https://electionlab.mit.edu/sites/default/files/2021-04/Blue-Shift-in-2020-Election.pdf

University of Florida's Election Lab early voting stats. https://election.lab.ufl.edu/early-vote/2024-early-voting/

Trump quotes from the 2020 election night are 01:09 to 01:20 and 07:31 to 08:22 from this video: https://www.youtube.com/watch?v=YlmaKdbC6ZM&ab_channel=ABCNews

CNN have a great timeline of what will happen when: https://edition.cnn.com/2024/11/02/politics/how-election-night-will-unfold-hour-by-hour/index.html

I found this to be a very helpful article: "Blue Shift And Red Mirage Explained: Why The First Vote Tallies May Be Misleading" https://www.forbes.com/sites/saradorn/2024/10/29/blue-shift-and-red-mirage-explained-why-the-first-vote-tallies-may-be-misleading/

Democracy sausage. You heard me. https://en.wikipedia.org/wiki/Democracy_sausage

If you have any suggestions for follow-on Election 2024 math videos, drop me a line: matt+election@standupmaths.com

Huge thanks to my Patreon supporters. They are the dark money super pac behind my channel. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Adequate filming by Matt Parker
Expert editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:6pLz8wEQYkA
title: New divisibility rule! (30,000 of them)
author: Stand-up Maths
url: https://www.youtube.com/watch?v=6pLz8wEQYkA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/6pLz8wEQYkA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Support me on Patreon before the end of November 2024 and get your own prime number test: https://www.patreon.com/standupmaths

Come and see Steve Mould, me and other humans on Monday 2 December in London. I'll be doing a free meet and great with Bec Hill after the show. https://festivalofthespokennerd.com/tickets/

Here is the current main list of divisibility tests from 7 to 30,000: https://www.dropbox.com/scl/fi/gl2e63e99jytv9nlc6loj/divisibility_tests_to_30000.txt?rlkey=0kfz6u2naf1ys129zs7pn1sok&dl=0

Divisibility Rules by Michael "Vsauce" Stevens on D!NG. https://www.youtube.com/watch?v=f6tHqOmIj1E

Why 7 is Weird by James Grime on Numberphile. https://www.youtube.com/watch?v=UDQjn_-pDSs

Buy signed props from the channel! All money goes to charity. https://www.ebay.co.uk/usr/standupmaths

Huge thanks to my Patreon supporters. They come together to support me dividing. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced and random numbers by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
Dice on loan from the Bec Hill Collection

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:wqOb5n3BIn0
title: 18 mathematicians break my secret santa method
author: Stand-up Maths
url: https://www.youtube.com/watch?v=wqOb5n3BIn0
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/wqOb5n3BIn0?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Learn more about Jane Street’s internship opportunities: https://jane-st.co/SUM-internships

Sign up to patreon to get a unique christmas card! https://www.patreon.com/standupmaths

A Mathematical Secret Santa Protocol by Katie Steckles https://www.youtube.com/watch?v=ehRTbNIr6-E

This is the math stackexchange discussion: https://math.stackexchange.com/a/2896914

The Problems with Secret Santa, Hannah fry on Numberphile. https://www.youtube.com/watch?v=5kC5k5QBqcc

Thanks to everyone who took part! Here they are in the same random order as the emails went around. Not everyone is active on youtube so you may need to google some people. Or there's a 40% chance they're in a Numberphile video somewhere.

1. Sam Hartburn https://www.youtube.com/@samhartburn
2. Matt Parker https://www.youtube.com/@standupmaths
3. Matthew Scroggs https://www.youtube.com/@scroggs2
4. Brady Haran https://www.youtube.com/@numberphile
5. Geoff Marshall https://www.youtube.com/@geofftech2
6. Henry Reich https://www.youtube.com/@MinutePhysics
7. Mithuna Yoganathan  https://www.youtube.com/@LookingGlassUniverse
8. Kat Phillips https://www.youtube.com/@KatDoesMaths
9. Steve Mould https://www.youtube.com/@SteveMould
10. Sophie Maclean https://www.youtube.com/@sophiemaclean9999
11. Peter Rowlett https://www.youtube.com/@peterrowlett
12. Katie Steckles https://www.youtube.com/@KatieSteckles
13. Grant Sanderson https://www.youtube.com/@3blue1brown
14. Tom Murphy VII https://www.youtube.com/@tom7
15. Destin Sandlin https://www.youtube.com/@smartereveryday
16. Ben Sparks https://www.youtube.com/@SparksMaths
17. Ayliean MacDonald https://www.youtube.com/@Ayliean
18. Rohin Francis https://www.youtube.com/@MedlifeCrisis

Huge thanks to my Patreon supporters. They're the real meaning of christmas. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything other than protocol improvement.

--- Ok, here is what he think is the current best protocol. We'll give it a try next year! ---

For people P1 to Pn.

Goals of the system:
- no central authority needed
- can be done remotely with no hidden information
- does not give anyone their own name
- no one malicious actor can do anything to exploit the system without risk of breaking everything

Be as random as possible. No new random number can match any already on the list.

STAGE 0: POPULATE THE LIST

Everyone adds a pair of random numbers, shuffles the list, and passes it on.

STAGE 1: DO THE SHUNT

P1 shuffles the list and then shunts the pairs along one space to form new pairs (last number wraps to first number).

Everyone from P2 to Pn-1 uses a 50% probability of also shunting an extra space in the same direction. Pn definitely does not shunt.

No one shuffles. Everyone replaces their random numbers.

STAGE 2: THE CHECK

Everyone looks to see where their numbers are and remembers their exact location. If they move at any point from now on, a player should raise the alarm that the system has been compromised.

No one shuffles. Everyone replaces their random numbers.

STAGE 3: THE BIG REVEAL

Everyone replaces their 'left numbers' (aka 'receiver IDs') with their name of any other agreed system for identifying people. The other number is replaced with a new random number, no one shuffles.

STAGE 4: THE READ OUT

Goes around the loop again with everyone looking to see whose name their random number is paired with. This is who they buy a gift for. They then cover their tracks by swapping out the random number for a new one.


--- And for completeness, here is the protocol exactly as we tried it in this video. ---

STAGE 0: POPULATE THE LIST

Everyone adds a pair of random numbers, shuffles the list, and passes it on.

STAGE 1: DO THE SHUNT

P1 shuffles the list and then shunts the pairs along one space to form new pairs (last number wraps to first number).

STAGE 2: SWAP THE LIST

Everyone replaces their first random number with their name and their second random number with a new random number.

STAGE 3: THE BIG REVEAL

Goes around the loop again with everyone looking to see whose name their random number is paired with. This is who they buy a gift for. They then cover their tracks by swapping out the random number for a new one.


Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced by Nicole Jacobus
Music by Howard Carter
Design by Simon Wright and Adam Robinson
Messing around by Everyone Else

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:Vv-lWg5HNaM
title: Do numerical pain scales mean anything?
author: Stand-up Maths
url: https://www.youtube.com/watch?v=Vv-lWg5HNaM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCSju5G2aFaWMqn-_0YBtq5A
enclosure_url: https://www.youtube.com/v/Vv-lWg5HNaM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Get 60 days free from Headspace from https://headspace-web.app.link/e/SUM or use voucher code STANDUPMATHS

Come and see the previews for my new untitled stand-up show on 10 February, 24 March and 23 June. Grab tickets now: https://festivalofthespokennerd.com/tickets/

Check out content from folk who bravely contributed data to the Schmatt Pain Index:
Mark Bowler: https://www.youtube.com/@aFieldBiologist - find out how we captured these insect in his latest video: https://youtu.be/ZACS1ck9n0c

Michael and Dani: https://www.instagram.com/the_wayfinders_/

Hugo Cliff: https://www.instagram.com/hugocliff_rainforest/

Greg Foot: https://www.instagram.com/gregfoot/ And Greg is doing a new schools talk "Rainforest Lab" https://www.gregfoot.com/talks

Thanks to Rainforest Expeditions for inviting us to visit their Research Centres in Peru and facilitating us getting stung by things in a safe environment. Read more about the research being done in the rainforest by Wired Amazon. They take science research volunteers as well as offering paid trips. 
https://www.wiredamazon.com/
https://www.youtube.com/@RainforestExpeditions
https://instagram.com/rainforestexpeditions/

Huge thanks to my Patreon supporters. Their support never stings. https://www.patreon.com/standupmaths

CORRECTIONS
- None yet, let me know if you spot anything! 

Filming and editing by Alex Genn-Bash
Written and performed by Matt Parker
Produced and drone piloted by Nicole Jacobus
Animations by William Marler 
Music by Howard Carter
Design by Simon Wright and Adam Robinson

MATT PARKER: Stand-up Mathematician
Website: http://standupmaths.com/


guid: yt:video:PG0wRb7eYms
title: Massive Memory Leaks in System76's Cosmic Desktop (Written in "Memory Safe" Rust)
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=PG0wRb7eYms
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/PG0wRb7eYms?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Plus: Hyprland developer weighs in, "No, I don't think it's beta ready :P"

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:0NGp77Fvm6A
title: Will The Linux Foundation Purchase Chrome?
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=0NGp77Fvm6A
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/0NGp77Fvm6A?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The courts are primed to force Google to sell Chrome, & Google is preparing by setting up a "Chrome" organization within The Linux Foundation.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:MNoqaYgF51g
title: 1980's Computers on the Modern Internet with FujiNet
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=MNoqaYgF51g
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/MNoqaYgF51g?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Because the Apple Il, 8 Bit Atari, Tandy Color Computer, and DOS PCs all deserve to be Online.

FujiNet website:
https://fujinet.online/

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:CltBX829Yjs
title: Apple Begs Shareholders to Let Them Continue Illegal DEl Policies
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=CltBX829Yjs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/CltBX829Yjs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
On February 25th, Apple Shareholders will vote on ending the company's illegal DEl policies.  The Apple Board recommends voting against "legal compliance", despite many Big Tech firms (including Meta, Amazon, and others) scaling back "Diversity, Equity, & Inclusion" programs -- and a flood of DEI related lawsuits (such as with IBM & Red Hat).

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:qnm6VmBfvTA
title: Tech Journalists Rally in Support of DEI in Big Tech
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=qnm6VmBfvTA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/qnm6VmBfvTA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
"Save me from rich, white men," declares the Tech Journalists in response to some Big Tech firms decreasing racist, sexist, discriminatory DEl spending.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:I-vGUzC75Ag
title: Godot Game Engine Went Woke... And Lost $160,000 Per Year.
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=I-vGUzC75Ag
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/I-vGUzC75Ag?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
A few months ago, the Open Source Godot Game Engine enacted a mass "cleansing" of Non-Woke supporters. Then their monthly donations dropped by over 25%.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:ig7gCNtdCGU
title: Linux Distro Declared "Non-Woke", Causing New Users & Interest to Skyrocket
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=ig7gCNtdCGU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/ig7gCNtdCGU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
While "Woke" Linux Distributions (like openSUSE) are struggling to survive, interest in OpenMandriva - a non-Woke Open Source project - is exploding.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:QDqzMaho21s
title: Linux Foundation's Mandatory DEI Training
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=QDqzMaho21s
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/QDqzMaho21s?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Lunduke takes the "Inclusive Open Source Community Orientation" certification, which focuses on BLM, Pronouns, Critical Race Theory, Micro-Inequities, and DEl.

That's right.  Lunduke is now "DEI Certified" by The Linux Foundation.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:BuJbFkGXC8M
title: Jack Dorsey Keynote Cancelled After Protest Threat by Child Porn Enthusiast, Extreme Leftist
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=BuJbFkGXC8M
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/BuJbFkGXC8M?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
"Billionaires are not welcome at FOSDEM," says Child Porn Enthusiast, Drew DeVault.  Largest Open Source Software Conference in Europe (FOSDEM) apparently agrees.

All of that reads like pure insanity... but it's all factual.  And not, in any way, exaggerated.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:xOdMTS6XVu4
title: No, Facebook is Not Censoring "Linux", Only "DistroWatch".
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=xOdMTS6XVu4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/xOdMTS6XVu4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Facebook is flagging and censoring links to DistroWatch.com as "malware".  But, despite what many are reporting, discussions of "Linux" are not censored.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:R86YqWIRywU
title: Microsoft Blizzard Artist Calls For Murder of Trump Voters
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=R86YqWIRywU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/R86YqWIRywU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
"Kill your local MAGA," says Activision Blizzard video game artist.  Parent company, Microsoft, has no comment but affirms commitment to DEl.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:3QuWqjJ1ZjM
title: DeepSeek is Copying Existing Al Data, Censoring Results, and Collecting Your Data for China
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=3QuWqjJ1ZjM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/3QuWqjJ1ZjM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
What do you get when you train your Al on an existing (error-filled) Al, censor it on behalf of a Communist government, and data mine your users? You get DeepSeek.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:YRVzPan3RLU
title: The Birth of a New Tech Myth: "Facebook Says Linux is Malware!"
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=YRVzPan3RLU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/YRVzPan3RLU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
We are witnessing a new "Computer Myth" being created before our eyes, as several "Tech News" outlets repeat a false statement about Facebook & Linux.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:vsKbj5bCS4A
title: Debian Linux Doubles Down on Wokeness, Leaves X.com
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=vsKbj5bCS4A
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/vsKbj5bCS4A?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Reasons for leaving X include "Elon Musk", "Diversity", "Fake News", & "Gender".

Because nothing says "professional, quality software engineering" quite like virtue signaling about gender diversity.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:8sbJEH81gJ0
title: Linux Foundation Makes Statement About Banning Russian Programmers (3 Months Late)
author: The Lunduke Journal
url: https://www.youtube.com/watch?v=8sbJEH81gJ0
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCkK9UDm_ZNrq_rIXCz3xCGA
enclosure_url: https://www.youtube.com/v/8sbJEH81gJ0?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
"It is disappointing that the open source community cannot operate independently of international sanctions programs," says Linux Foundation.

More from The Lunduke Journal:
https://lunduke.com/


guid: yt:video:JNVZK4ofW-Y
title: The Triangle Of Power
author: 3Blue1Brown
url: https://www.youtube.com/watch?v=JNVZK4ofW-Y
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw
enclosure_url: https://www.youtube.com/v/JNVZK4ofW-Y?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The referenced stack exchange post by usename 2'5 9'2,  http://math.stackexchange.com/questions/30046/alternative-notation-for-exponents-logs-and-roots


guid: yt:video:LPZh9BOjkQs
title: Large Language Models explained briefly
author: 3Blue1Brown
url: https://www.youtube.com/watch?v=LPZh9BOjkQs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw
enclosure_url: https://www.youtube.com/v/LPZh9BOjkQs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Dig deeper here: https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi
Technical details as a talk: https://youtu.be/KJtZARuO3JY
This was made for an exhibit at the Computer History Museum: https://computerhistory.org/
Instead of sponsored ad reads, these lessons are funded directly by viewers: https://3b1b.co/support

No secret end-screen vlog for this one, the end-screen real estate was all full!

------------------

These animations are largely made using a custom Python library, manim.  See the FAQ comments here:
https://3b1b.co/faq#manim
https://github.com/3b1b/manim
https://github.com/ManimCommunity/manim/

All code for specific videos is visible here:
https://github.com/3b1b/videos/

The music is by Vincent Rubinetti.
https://www.vincentrubinetti.com
https://vincerubinetti.bandcamp.com/album/the-music-of-3blue1brown
https://open.spotify.com/album/1dVyjwS8FBqXhRunaG5W5u

------------------

3blue1brown is a channel about animating math, in all senses of the word animate. If you're reading the bottom of a video description, I'm guessing you're more interested than the average viewer in lessons here. It would mean a lot to me if you chose to stay up to date on new ones, either by subscribing here on YouTube or otherwise following on whichever platform below you check most regularly.

Mailing list: https://3blue1brown.substack.com
Twitter: https://twitter.com/3blue1brown
Instagram: https://www.instagram.com/3blue1brown
Reddit: https://www.reddit.com/r/3blue1brown
Facebook: https://www.facebook.com/3blue1brown
Patreon: https://patreon.com/3blue1brown
Website: https://www.3blue1brown.com


guid: yt:video:y9BK--OxZpY
title: The meaning within the Mandelbrot set
author: 3Blue1Brown
url: https://www.youtube.com/watch?v=y9BK--OxZpY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw
enclosure_url: https://www.youtube.com/v/y9BK--OxZpY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The full video dives deeper into the field of math studying this called holomorphic dynamics: https://youtu.be/LqbZpur38nw


guid: yt:video:IQqtsm-bBRU
title: This open problem taught me what topology is
author: 3Blue1Brown
url: https://www.youtube.com/watch?v=IQqtsm-bBRU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw
enclosure_url: https://www.youtube.com/v/IQqtsm-bBRU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The inscribed square/rectangle problem, solved using Möbius strips and Klein bottles.
Playlist with more neat proofs: https://www.youtube.com/playlist?list=PLZHQObOWTQDPSKntUcMArGheySM4gL7wS
Instead of sponsored ad reads, these lessons are funded directly by viewers: https://3b1b.co/support
An equally valuable form of support is to simply share the videos.

This argument was originally by Herbert Vaughan, appearing for examples in this issue of the Topology Proceedings.
https://topology.nipissingu.ca/tp/reprints/v06/tp06107.pdf

The on-screen argument for why all closed non-orientable surfaces must intersect themselves in 3d is a slight variation on one I heard from Dan Asimov.

2020 Paper by Greene and Lobb:
https://arxiv.org/pdf/2005.09193

Nice Quanta article about this result:
https://www.quantamagazine.org/new-geometric-perspective-cracks-old-problem-about-rectangles-20200625/

Timestamps:
0:00 - Inscribed squares
1:00 - Preface to the second edition
3:04 - The main surface
10:47 - The secret surface
16:45 - Klein bottles
22:38 - Why are squares harder?
25:10 - What is topology?

------------------

These animations are largely made using a custom Python library, manim.  See the FAQ comments here:
https://3b1b.co/faq#manim
https://github.com/3b1b/manim
https://github.com/ManimCommunity/manim/

All code for specific videos is visible here:
https://github.com/3b1b/videos/

The music is by Vincent Rubinetti.
https://www.vincentrubinetti.com
https://vincerubinetti.bandcamp.com/album/the-music-of-3blue1brown
https://open.spotify.com/album/1dVyjwS8FBqXhRunaG5W5u

------------------

3blue1brown is a channel about animating math, in all senses of the word animate. If you're reading the bottom of a video description, I'm guessing you're more interested than the average viewer in lessons here. It would mean a lot to me if you chose to stay up to date on new ones, either by subscribing here on YouTube or otherwise following on whichever platform below you check most regularly.

Mailing list: https://3blue1brown.substack.com
Twitter: https://twitter.com/3blue1brown
Instagram: https://www.instagram.com/3blue1brown
Reddit: https://www.reddit.com/r/3blue1brown
Facebook: https://www.facebook.com/3blue1brown
Patreon: https://patreon.com/3blue1brown
Website: https://www.3blue1brown.com


guid: yt:video:0TdBP9m4R74
title: The barber pole optical mystery
author: 3Blue1Brown
url: https://www.youtube.com/watch?v=0TdBP9m4R74
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw
enclosure_url: https://www.youtube.com/v/0TdBP9m4R74?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Series exploring optics: https://www.youtube.com/watch?v=QCX62YJCmGk&list=PLZHQObOWTQDMKqfyUvG2kTlYt-QQ2x-ui


guid: yt:video:sxi0-Y_RWsU
title: Why Bugs Are Attracted To Light SOLVED - Mind Blow
author: Vsauce2
url: https://www.youtube.com/watch?v=sxi0-Y_RWsU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/sxi0-Y_RWsU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Use code VSAUCE250 to get 50% off your first Factor box at https://bit.ly/3mG5rbL!
Thanks to Factor for sponsoring Vsauce2.

Get Ad-Free Mind Blow on Patreon: https://www.patreon.com/Vsauce2

In this episode  of Mind Blow on Vsauce2: scientists have a new hypothesis for why bugs fly around light bulbs, we learn of secret science new virus hiding in baby diapers, in space news Einstein helped discover a massive black hole, a simple drought solution, fruit helping recycle batteries, an ancient Egyptian gifting custom now has physical evidence, a massive leap in MRI brain scan technology, and bioadhesives just got stronger and safer for surgery. The type of science news found only on Mind Blow by Vsauce2.

Patron Thanks

BENEFACTOR
Xemboy01

EXECUTIVE PRODUCERS
Brent Tiggelaar, Ian Fabs, Wolfgang Hutton, NullBlox.ZachryWilsn, Jonathan Hawk, Markus Fleischer, Thomas Kaminski

*** SOURCES ***

Why flying insects gather at artificial light (0:00)
https://www.biorxiv.org/content/10.1101/2023.04.11.536486v1

Expanding known viral diversity in the healthy infant gut (0:39)
https://www.nature.com/articles/s41564-023-01345-7

Abell 1201: detection of an ultramassive black hole in a strong gravitational lens (1:27)
https://academic.oup.com/mnras/article/521/3/3298/7085506

Structure-guided engineering of a receptor-agonist pair for inducible activation of the ABA adaptive response to drought (2:08)
https://www.science.org/doi/10.1126/sciadv.ade9948

Brain Images Just Got 64 Million Times Sharper (3:49)
https://today.duke.edu/2023/04/brain-images-just-got-64-million-times-sharper

NTU Singapore and Se-cure Waste Management build pilot recycling plant to tackle lithium-ion battery waste with biomass waste (4:30)
https://www.eurekalert.org/news-releases/984142

First osteological evidence of severed hands in Ancient Egypt (5:07)
https://www.nature.com/articles/s41598-023-32165-8

Injectable gelatin-oligo-catechol conjugates for tough thermosensitive bioadhesion (5:40)
https://www.sciencedirect.com/science/article/pii/S2666386423000140?via%3Dihub

Database, 1984 (6:40)
https://www.youtube.com/watch?v=szdbKz5CyhA


*** CREDITS ***

Hosted and Created by Kevin Lieber
https://twitter.com/VsauceTwo

Research and Writing by Scott Frank
https://twitter.com/hollywoodsapien

Graphics and Editing by Vic Grimes
https://twitter.com/VicGrimes

Special Thanks John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Fact Checking by Geoff Barrett
https://twitter.com/GeoffdBarrett

Watch more science news, tech news, space news, and educational videos like Mind Blow with the Vsauce crew on our channel!

#MindBlow #Vsauce #ScienceNews #science #Education


guid: yt:video:9nVL9nSix1A
title: Does Happiness Make You Happy?
author: Vsauce2
url: https://www.youtube.com/watch?v=9nVL9nSix1A
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/9nVL9nSix1A?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Check out https://www.piavpn.com/Vsauce2 for an 83% discount on Private Internet Access! That’s $2.03 a month and get 4 extra months free!

Vsauce2 dives into the fundamental meaning behind the concept of "happy" and how our twisted modern take on happiness is making things measurably worse. What is the paradox of chasing happiness? And how to things we think will make us happy actually lead to depression?

Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

*** CREDITS ***

Vsauce2:
TikTok: https://www.tiktok.com/@vsaucetwo
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Additional Editing by Vic Grimes
https://twitter.com/VicGrimes

Huge Thanks To Paula Lieber
https://www.etsy.com/shop/Craftality

Vsauce's Curiosity Box: https://www.curiositybox.com/

Watch more science news, tech news, psychology facts, and educational videos like Mind Blow with the Vsauce crew on our channel!

#vsauce #psychology #science #mentalhealth


guid: yt:video:2vSufrs32fQ
title: GROWING Computers In Your Backyard? -- Mind Blow
author: Vsauce2
url: https://www.youtube.com/watch?v=2vSufrs32fQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/2vSufrs32fQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
FUTO Fellows applications are open until June 5th. Learn more at https://futo.org/fellows/ and send your idea to grantapps@futo.org

Get Ad-Free Mind Blow on Patreon: https://www.patreon.com/Vsauce2

In this episode of Mind Blow on Vsauce2: the ruins of Ancient Rome reveal interesting medical devices, a new humanoid robot learns to be just like you, scientists develop a neural brain implant that works like an octopus, Team Trees might have accidentally grown 20 million computers with wood transistors, Stone Age architectural plans reveal sophisticated abstract cognitive abilities, olfactory virtual reality now includes scents and smells, the Titanic gets 3D mapped with over 700,000 images, which may reveal clues about how the Titanic sank, and the glassy-winged sharpshooter contributes to our biological understanding of fluid dynamics with its built-in butt catapult.

Patron Thanks

BENEFACTOR
Xemboy01

EXECUTIVE PRODUCERS
Brent Tiggelaar, Ian Fabs, Jonathan Hawk, Markus Fleischer,  NullBlox.ZachryWilsn, Thomas Kaminski, Wolfgang Hutton.

*** SOURCES ***

Wood Electrochemical Transistor (0:00)
https://www.pnas.org/doi/10.1073/pnas.2218380120

First Ever Full-Sized Scans of Titanic Shipwreck (0:49)
https://www.magellan.gg/titanic-in-3d/

Roman Urine Flasks (1:48)
https://www.cambridge.org/core/journals/antiquity/article/disease-control-and-the-disposal-of-infectious-materials-in-renaissance-rome-excavations-in-the-area-of-caesars-forum/F43A8803C6D74D01C4C07DC0D4C81094

Sanctuary AI (2:31)
https://www.sanctuary.ai/

Soft Robot Brain Implant (3:11)
https://www.science.org/doi/10.1126/scirobotics.add1002

Stone Age Blueprints (5:04)
https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0277927

VR Smells (5:45)
https://www.nature.com/articles/s41467-023-37678-4

Superfast Insect Urination (6:48)
https://research.gatech.edu/super-fast-insect-urination-powered-physics-superpropulsion

Sony Walkman Commercial 1983 (7:55)
https://www.youtube.com/watch?v=7lipckhgG5g

*** CREDITS ***

Hosted, Researched and Created by Kevin Lieber
https://twitter.com/VsauceTwo

Written by Matthew Tabor
https://twitter.com/TaborTCU

Edited by John Swan
https://www.youtube.com/@JohnSwanYT

Fact Checking by Geoff Barrett
https://twitter.com/GeoffdBarrett

Watch more science news, tech news, space news, and educational videos like Mind Blow with the Vsauce crew on our channel!

#MindBlow #Vsauce #ScienceNews #science #Education #shorts #science #scienceshorts


guid: yt:video:hax2be-DlhY
title: Does Pain Actually Hurt?
author: Vsauce2
url: https://www.youtube.com/watch?v=hax2be-DlhY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/hax2be-DlhY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
For 16 free meals with HelloFresh PLUS free shipping, use code 16VSAUCE2 at https://bit.ly/3HxQgso

Please support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

When we think of the human experience, we tend to focus on the good things: love, happiness, and progress. But what if the most important part of our lives is actually one of the worst? Our relationship with pain stretches back further than any other sensation, and it turns out that pain has been and continues to be our most important teacher. We paradoxically need something awful to survive. Vsauce2 explores the science and psychology of pain going all the way back to our four-legged ancestors. 

Despite pain dictating daily life for millions of years, we’ve only come to understand exactly how it works fairly recently. We now know the exact physiological mechanisms of how pain works within our bodies -- which evolved from rudimentary scientific theories from Descartes and others -- but we’re still figuring out how it works within our minds. And as we navigate the science of it all, from neuroscience to psychology, we uncover more questions than ever. Should we eliminate pain, or should we learn to live with it? What happens to our identities when we take all the pain away, and is it worth the cost to ourselves? What is society’s responsibility to relieve pain, and how does politics factor in? How much of your pain is real and how much pain is essentially imagined?

On the surface it seems like an ideal world would be one completely devoid of pain, with strong mental health in conjunction with physical wellness. But the reality is more complex, and it’s worth thinking about the implications of the convoluted link between pain and suffering that we can’t live with… and can’t live without.

*** CREDITS ***

Vsauce2:
TikTok: https://www.tiktok.com/@vsaucetwo
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber
https://www.etsy.com/shop/Craftality

Vsauce's Curiosity Box: https://www.curiositybox.com/

#MindBlow #Vsauce #ScienceNews #science #Education


guid: yt:video:oBRtKj7kl_o
title: Gamers Will Live Forever - Mind Blow
author: Vsauce2
url: https://www.youtube.com/watch?v=oBRtKj7kl_o
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/oBRtKj7kl_o?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Check out https://guard.io/Vsauce2 for a 7-day trial and 20% off your subscription + the ability to protect 5 family members from hackers and scammers!

Get Ad-Free Mind Blow on Patreon: https://www.patreon.com/Vsauce2

Could one of the staples of a gamer’s diet actually improve physiological health the same way it has for mice and worms? Is it possible to harness plant photosynthesis with a synthetic leaf that mirrors the same chemical process to replace fossil fuels? Will small armies of robot cartographers replace Google Street View cars -- and eventually explore the unknowns of Earth’s oceans? How long have hominins existed in Greece, and are our Mediterranean ancestors hundreds of thousands of years older than we think?

The James Webb Space Telescope has just captured images of molecules over 12 billion light years away -- but are they just specks of matter, or are they the building blocks of stars?
Han Solo’s nap in carbonite might just be a part of your own future now that mice have been induced into a state of torpor -- and it has implications for improving emergency medicine. The idea of inducing torpor was first proposed to reduce the physical demands of space travel, and when you finally cruise to Mars, who knows how many arms and legs you’ll have? Researchers at MIT have tacked on a pair of supernumerary limbs that gets us one step closer to being space octopuses.
The future of science and technology gets more exciting by the day, but we continue to uncover amazing elements of our past -- like a 3,000 year old sword in Bavaria that has been preserved so well that its blade still shines. Past. Present. Future. Mind Blow!

Patron Thanks

BENEFACTOR
Xemboy01

EXECUTIVE PRODUCERS
Brent Tiggelaar, Ian Fabs, Jonathan Hawk, Markus Fleischer,  NullBlox.ZachryWilsn, Thomas Kaminski, Wolfgang Hutton

Taurine Anti-Aging (0:00)
https://www.science.org/doi/10.1126/science.adi3025

Artificial Leaf (0:59)
https://www.nature.com/articles/s41560-023-01262-3#Sec21

Multi Robot Mapping (1:45)
https://arxiv.org/pdf/2106.14386.pdf

Oldest Evidence of Humans In Greece (2:29)
https://www.livescience.com/archaeology/oldest-evidence-of-humans-in-greece-is-700000-years-old-a-quarter-of-a-million-years-older-than-previously-thought

James Webb Telescope Discovers Oldest Organic Molecules (4:37)
https://www.nature.com/articles/d41586-023-01844-x

Ultrasound Deep Sleep (5:38)
https://www.nature.com/articles/s42255-023-00804-z

Supernumerary Limbs For Space Suit (6:38)
https://www.youtube.com/watch?v=Wed7JAyfLyA

Shining Bronze Age Octagonal Sword (7:12)
https://www.blfd.bayern.de/mam/blfd/presse/pi_bronzezeitliches_schwert.pdf

Introducing The Amazing Compact Disc (7:42)
https://www.youtube.com/watch?v=_Tx6TYnPat8

*** CREDITS ***

Hosted, Researched and Created by Kevin Lieber
https://twitter.com/VsauceTwo

Written by Matthew Tabor
https://twitter.com/TaborTCU

Edited by Vic Grimes
https://twitter.com/VicGrimes

Fact Checking by Geoff Barrett
https://twitter.com/GeoffdBarrett

Watch more science news, tech news, space news, and educational videos like Mind Blow with the Vsauce crew on our channel!

#MindBlow #Vsauce #ScienceNews #science #Education #shorts #science #scienceshorts


guid: yt:video:UA0VeadObfM
title: Hand Smell Predicts Gender? - Mind Blow
author: Vsauce2
url: https://www.youtube.com/watch?v=UA0VeadObfM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/UA0VeadObfM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Thanks to Storyblocks for sponsoring this video! Download unlimited stock media at one set price with Storyblocks: https://storyblocks.com/Vsauce2

Get Ad-Free Mind Blow on Patreon: https://www.patreon.com/Vsauce2

This science research doesn’t just pass the sniff test -- it IS the sniff test. Our olfactory abilities are so refined that our noses can identify a person’s gender with over 96% accuracy from the smell of their… hands?!

Robotics is advancing past clumsy limbs and brute force by getting better at both -- this rolling robot that can make deliveries, throw objects, and dynamically adjust its application of force.

Sometimes our most advanced scientific discoveries already exist in nature -- like a tiny pill modeled after the pangolin that can roll up to be deployed in internal medicine applications. Oh, and it’s moved around your body by a magnet.

A scientific breakthrough has been sitting at the bottom of a canyon for decades -- and despite it being over 100 meters high, we’re only just seeing Asia’s tallest tree.

Birds are once again dominating the science news cycle, and this time it’s by thumbing their beaks at our efforts to deter them from public spaces. It seems like anti-bird spikes actually make great bird castles.

Until recently, bionic limbs have been rudimentary with little fine motor control -- but harnessing AI algorithms, neuroscience, and osseointegration may allow for natural motions in bionic hands and fingers.

The dark side of the Moon continues to keep secrets, like why there’s a giant slab of thorium and uranium resulting from a billion-year old moon volcano.

A giant 300,000 year old flint axe has been discovered in England, and it either hurt people, hunted animals, or just looked awesome.

Patron Thanks

BENEFACTOR
Xemboy01

EXECUTIVE PRODUCERS
Brent Tiggelaar, Ian Fabs, Jonathan Hawk, Markus Fleischer,  NullBlox.ZachryWilsn, Thomas Kaminski, Wolfgang Hutton

*** SOURCES ***

Hand Sniff Identifies Gender (0:00)
https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0286452

Wheeled Humanoid Controlled by Whole-Body Teleoperation (0:40)
https://publish.illinois.edu/robodesign/

Tiny Pangolin-Inspired Medical Robot (1:23)
https://www.nature.com/articles/s41467-023-38689-x

Asia’s Tallest Tree (2:13)
https://newsen.pku.edu.cn/news_events/news/research/13432.html

Birds Building Anti-Bird Nests (3:53)
https://www.hetnatuurhistorisch.nl/fileadmin/user_upload/documents-nmr/Publicaties/Deinsea/Deinsea_21/Deinsea_21_17_25_2023_Hiemstra_et_al.pdf

Bionic Hand Individual Finger Control  (4:39)
https://www.sciencedaily.com/releases/2023/07/230712165138.htm

Radioactive Granite Buried On Moon (5:24)
https://www.nature.com/articles/s41586-023-06183-5.epdf

Britain’s Oldest and Largest Stone Age Tools (6:17)
https://www.ucl.ac.uk/news/2023/jul/giant-stone-artefacts-found-rare-ice-age-site-kent

Lady Kenmore Dishwasher Commercial, 1974 (7:04) 
https://www.youtube.com/watch?v=QUrDobvRLcA


*** CREDITS ***

Hosted, Researched and Created by Kevin Lieber
https://twitter.com/VsauceTwo

Written by Matthew Tabor
https://twitter.com/TaborTCU

Edited by Vic Grimes
https://twitter.com/VicGrimes

Fact Checking by Geoff Barrett
https://twitter.com/GeoffdBarrett

Watch more science news, tech news, space news, and educational videos like Mind Blow with the Vsauce crew on our channel!

#mindblow #vsauce #science #robotics #technology #sciencefacts


guid: yt:video:H7haxkYwAaU
title: Should You Be A Psychopath?
author: Vsauce2
url: https://www.youtube.com/watch?v=H7haxkYwAaU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/H7haxkYwAaU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Use code VSAUCE250 to get 50% off your first Factor box at https://bit.ly/3mG5rbL

Please support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

You almost certainly know a psychopath in real life… and you may very well be one yourself. And that might even be a good thing.

We’ve recognized psychopathy in science and culture for thousands of years, yet we still don’t know what to do about it. Yet we use the word itself now more than ever, so much that the meaning of the word “psychopath” has become diluted in popular culture. As we increasingly learn more about the science of psychopathy, we should get better at deploying the term more accurately -- but instead, it’s become a catch-all for unconscionable human behavior and a mainstay of true crime stories.

Psychopaths are much more complex than that… for better and worse.

In reality, a psychopath’s brain creates and perpetually reinforces a moral code that is defined more by what it lacks than what it contains. From a total absence of anxiety to a simple utilitarian worldview that can do tremendous harm to others, the psychopath is a mix of brute force and the most subtle manipulation. And this is where it gets really complicated: you actually want the ruthlessness of a psychopath to run your company, you want the charm of a psychopath for investigative journalism, and you want the fearlessness of a psychopath to respond to medical emergencies.

Can we harness the biological and psychological forces that create dangerous, destructive psychopaths to improve humanity? And if we could cure or eliminate psychopathy… would we even want to?

ADDITIONAL READING

Kiehl, Kent. “The Psychopath Whisperer: The Science of Those Without Conscience.” https://www.amazon.com/Psychopath-Whisperer-Science-Without-Conscience/dp/0770435866

Dutton, Kevin. “The Wisdom of Psychopaths: What Saints, Spies, and Serial Killers Can Teach Us About Success.” https://www.amazon.com/Wisdom-Psychopaths-Saints-Killers-Success/dp/0374533989

*** CREDITS ***

Vsauce2:
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
TikTok: https://www.tiktok.com/@vsaucetwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber
https://www.etsy.com/shop/Craftality

Vsauce's Curiosity Box: https://www.curiositybox.com/

#psychology #truecrime #psychopath #mentalhealth #science


guid: yt:video:OGjPaJ1MtmY
title: The Baby Bum - Mind Blow
author: Vsauce2
url: https://www.youtube.com/watch?v=OGjPaJ1MtmY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/OGjPaJ1MtmY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Thanks to Storyblocks for sponsoring this video! Download unlimited stock media at one set price with Storyblocks: https://storyblocks.com/Vsauce2

Get Ad-Free Mind Blow on Patreon: https://www.patreon.com/Vsauce2

Patron Thanks

BENEFACTOR
Xemboy01

EXECUTIVE PRODUCERS
Brent Tiggelaar, Ian Fabs, Jonathan Hawk, Markus Fleischer,  NullBlox.ZachryWilsn, Thomas Kaminski, Wolfgang Hutton

You discover a new species of succulent. It’s composed of two tiny butt cheeks. What do you call it? BABY BUM. And there’s really no possible alternative, because this is Mind Blow.
An array of 100 robotic muscles that can flex 50 times per second is like a giant fluid trampoline with haptic response that can move and sort objects and also generate images. It’s like a waterbed mixed with a computer. What more could you need?

We talk a lot about AI in art, but we’re making fantastic progress in using AI to fuel neural bypass connections -- like an electronic brain-body-spinal cord bridge that has brought back movement and sensation in the limbs of a man with quadriplegia.

A full decade ago, Mind Blow highlighted the weirdly anti-bacterial wings of the clanger cicada. By analyzing the nanostructure of the wings, we finally know how the nanopillars on the wings kill bacteria and clean the surface -- and it has tremendous implications for sanitizing the surfaces of medical devices.

A 600-pound asteroid is coming directly for your head… sort of. It’s 13 million miles away, which means it’s classified as a “potentially hazardous asteroid,” and it’s tracked twice a day with a 3,200 megapixel camera. They say you never hear the one that gets you.

Spiders are incredible at pulling moisture from the air, and they do it by constructing webs on which droplets collect easily and efficiently. Replicating their process allows water collection to happen without expending energy. Science smarter, not harder.

What if tattoos could be functional instead of purely aesthetic? Nanotech’s got it covered, starting with individual cells. 3-D bioprinting technology can place a flexible tattoo that functions as a data collection and warning system for the body.

40 years ago we discovered fantastic fossils of the immortal jellyfish… and no one bothered to look at them until now, because sometimes science news takes a couple generations to develop. But the Canadian fossils are so detailed that some even reveal an animal’s last meal. They show that jellyfish as we know them today are even older than we thought -- but they’re still an aquatic whippersnapper compared to the sea sponge.

*** SOURCES ***

Baby Bum Succulent (0:00)
https://www.livescience.com/planet-earth/plants/this-bizarre-little-succulent-looks-like-a-babys-butt

Shape-Shifting Display For 3D Designs (0:33)
https://www.nature.com/articles/s41467-023-39842-2

A.I. Brain Implant (1:23)
https://www.northwell.edu/news/the-latest/bioelectronic-medicine-researchers-restore-feeling-lasting-movement-in-quadriplegic-man

Cicada Wings Kill Superbugs on Contact (2:06)
https://pubs.acs.org/doi/10.1021/acsami.2c18121

New Algorithm Ensnares Asteroid (3:43)
https://www.washington.edu/news/2023/07/31/heliolinc3d/

Spider Web Fog-Water Collection (4:33)
https://onlinelibrary.wiley.com/doi/abs/10.1002/adfm.202305244

Nanoscale Tattoos For Cells (5:17)
https://pubs.acs.org/doi/10.1021/acs.nanolett.3c01960 

500 Million Year Old Jellyfish (5:58)
https://royalsocietypublishing.org/doi/10.1098/rspb.2022.2490

RCA XL-100 TV Set Commercial, 1975 (6:55)
https://www.youtube.com/watch?v=utYZN9WGqZw


*** CREDITS ***

Hosted, Researched and Created by Kevin Lieber
https://twitter.com/VsauceTwo

Written by Matthew Tabor
https://twitter.com/TaborTCU

Edited by Vic Grimes
https://twitter.com/VicGrimes

Fact Checking by Geoff Barrett
https://twitter.com/GeoffdBarrett

Watch more science news, tech news, space news, and educational videos like Mind Blow with the Vsauce crew on our channel!

#MindBlow #Vsauce #ScienceNews #science #Education #science #scienceshorts #shorts


guid: yt:video:okOfvMY5wOI
title: The Man Killed For Saving The World
author: Vsauce2
url: https://www.youtube.com/watch?v=okOfvMY5wOI
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/okOfvMY5wOI?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Use code VSAUCE250 to get 50% off your first Factor box at https://bit.ly/3mG5rbL

Please support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

When we look back on the history of science and scientific progress, we celebrate the pioneers who dared to make life-changing discoveries. The truth is that the first people to introduce a paradigm-shift almost always face persecution, and many are overshadowed by the less-controversial minds who follow them.

Such is the case of Ignaz Semmelweis, a Hungarian doctor who fought a lifelong battle against a disease he couldn’t see and that the medical establishment repeatedly told him wasn’t real. How does a scientist or doctor combat bacteria when they don’t even know it exists? The epidemics bacteria, viruses, and germs brought to innocent hospital patients wracked hospitals of the day, but the history of medicine is as much one of complacency and cosmic explanations as it is about breakthroughs.

Ignaz Semmelweis used incredible powers of logic and deductive reasoning to isolate a problem so complex that it stymied all the scientific minds of continental Europe, first by examining data within the clinics of his own hospital, and then identifying the source of infection. Through years of refining an antiseptic regimen that would end up saving an incalculable number of lives -- and paving the way for better-known scientific giants like Lister and Pasteur -- Semmelweis compiled one of the era’s great medical texts, one that would change healthcare worldwide.

And for that, he was ridiculed, criticized, fired, dismissed, institutionalized, and beaten to de*th. The shocking story of Ignaz Semmelweis is the real story of scientific progress.

*** Additional Reading ***

Semmelweis, Ignaz. “The Etiology, Concept, and Prophylaxis of Childbed Fever,” 1861; Translated by K. Codell Carter, 1983: https://www.amazon.com/Etiology-Prophylaxis-Childbed-Wisconsin-Publications/dp/0299093646

Semmelweis, Fjernsynsteatret (Television Theater, Norway), 1983: https://tv.nrk.no/serie/fjernsynsteatret/1983/FTEA00005183

Semmelweis, 1952 (Courtesy of the Hungarian National Film Archive): https://youtu.be/z3Xg5mXW218

Sla*ghter, Frank J. “Immortal Magyar: Semmelweis, Conqueror of Childbed Fever,” 1950: https://www.amazon.com/Immortal-Magyar-Semmelweis-Conqueror-Childbed/dp/B0006ASE5M

Obenchain, Theodore G. “Genius Belabored: Childbed Fever and the Tragic Life of Ignaz Semmelweis,” 2016: https://www.amazon.com/Genius-Belabored-Childbed-Tragic-Semmelweis/dp/0817319298

*** CREDITS ***

Vsauce2:
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
TikTok: https://www.tiktok.com/@vsaucetwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber

Vsauce's Curiosity Box: https://www.curiositybox.com/

#semmelweis #history #medicine #surgery #germs


guid: yt:video:srJBLo8GR5g
title: The Man Who Wants Us Dead
author: Vsauce2
url: https://www.youtube.com/watch?v=srJBLo8GR5g
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/srJBLo8GR5g?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The biggest bomb doesn't explode how you would think. Let's explore the population bomb.
Subscribe to the Foundation for Economic Education: https://bit.ly/feeyt
The Population Bomb by Paul Ehrlich: https://amzn.to/3Mo3lH5

10 Reasons We’re Wrong About the World by Hans Rosling: https://amzn.to/3FELJDc

The Ultimate Resource by Julian Simon: https://amzn.to/3MlE3JM

Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

The most pressing threat to civilization is us -- and paradoxically, we’re also the solution. When Paul Ehrlich published “The Population Bomb” in 1968, he ushered in an era of doomsday predictions that we’re still in. There are more than twice as many people in the world now than when his book came out, and Ehrlich insists that the population bomb just hasn’t gone off yet. 

But optimists like Julian Simon see something else happening. They acknowledge that man-made threats of destruction are not only challenges we can solve -- and that we’re in a better position every day to eliminate our problems -- but that we’re also better off for it. 

The philosophical differences between Ehrlich and Simon led to the most famous bet in the world, a bet over natural resources that was really a bet about the future of the human race. And as wrong as Paul Ehrlich has proven to be, we’re so hard-wired to think like him that it’s actually perfectly reasonable to conclude we’re perpetually facing disaster.

*** CREDITS ***

Vsauce2
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
TikTok: https://www.tiktok.com/@vsaucetwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber

Vsauce's Curiosity Box: https://www.curiositybox.com/

What did you think about the population theory of The Population Bomb by Paul Ehrlich? Subscribe for more science, history, and education videos every month!
#Education #Science #Vsauce #History #doomsday #Humanity #populationbomb


guid: yt:video:AhSBQOTW018
title: The Man Who Killed Millions Trying To Grow Food In Snow
author: Vsauce2
url: https://www.youtube.com/watch?v=AhSBQOTW018
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/AhSBQOTW018?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

There’s more to the story of Trofim Lysenko and the Soviet Union’s most disastrous era of science than you probably realize. Everyone knows of “Lysenkoism” regarding the USSR’s failed theories of genetics, but Trofim Lysenko’s lifelong body work was driven by a perfect combination of history, revolution, political theory, power, and personalities.

Lysenko’s impact on Russian biology was a direct result of crafting science -- and scientists -- in service of Vladimir Lenin’s new Soviet man at a time when the international scientific community was making tremendous progress on genetics and biology. But to Lysenko and Josef Stalin, the real science was in the potential of plants and animals to behave like Soviet citizens.

That led Russia and its scientists down a path that derailed progress for decades. But what if Lysenko’s theories on the inheritance of acquired traits actually have merit? A resurgence of support for Lysenko has gone beyond the grim history of science to look at what we know about altering the expression of DNA and how a human’s experiences in life can even affect their grandchildren. The truth is that modern genetics has little to nothing to do with Lysenko, but the specter of his pseudoscience continues to haunt the disciplines of genetics and biology -- and science as a whole.

*** SOURCES / ADDITIONAL READING ***

“Lysenko’s Ghost: Epigenetics and Russia” by Loren Graham: https://bit.ly/3ReCEpT

“A People's Tragedy: The Russian Revolution: 1891-1924” by Orlando Figes: https://bit.ly/4a8Ti32

“Stalin and the Scientists: A History of Triumph and Tragedy” by Simon Ings: https://amzn.to/3RwD5NE

*** CREDITS ***

Vsauce2
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
TikTok: https://www.tiktok.com/@vsaucetwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber

Vsauce's Curiosity Box: https://www.curiositybox.com/

#science #scientist #history


guid: yt:video:YxsXyBzP1jE
title: They Starved Surrounded By Food
author: Vsauce2
url: https://www.youtube.com/watch?v=YxsXyBzP1jE
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/YxsXyBzP1jE?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Try Rocket Money for free: https://RocketMoney.com/vsauce2  #rocketmoney #personalfinance 

Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

The life, death, and legacy of Russian geneticist Nikolai Vavilov isn’t just one of the most compelling science stories of the 20th century -- it’s a combination of scientific progress, human resilience, and a celebration of both the scientific and human spirits.

Vavilov’s tumultuous career in biology and genetics flowed from Vladimir Lenin’s support to Trofim Lysenko’s hostility to Joseph Stalin’s outright persecution. And while Vavilov himself succumbed to Stalin’s scapegoating and purges, his groundbreaking efforts to create a global seedbank for the betterment of mankind inspired his peers to endure suffering beyond comprehension in the service of science.

The staff of Vavilov’s plant institute endured the nearly 3-year Siege of Leningrad: no heat, no safety, and most importantly, no sustenance. But while the rest of the city struggled to survive in conditions of starvation, Vavilov’s peers and staff were actually surrounded by the one thing that would keep them alive: food.

Dozens of scientists met their deaths to protect Vavilov’s vision despite protecting tons of the exact material that would keep them alive.

They did it for Vavilov, they did it for humanity, and they did it for science.

*** FURTHER READING/VIEWING ***

"The Murder of Nikolai Vavilov" by Peter Pringle: https://amzn.to/3RPfCrf

"Stalin and the Scientists: A History of Triumph and Tragedy" by Simon Ings: https://amzn.to/3GSOukP

"The Scientist, the Imposter and Stalin" from Icarus Films: https://vimeo.com/ondemand/scientist

"The Man Who Haunts Science" by Vsauce2: https://www.youtube.com/watch?v=AhSBQOTW018

"The Scapegoat Mechanism" by Vsauce2: https://youtu.be/lNJq6BlVyhM

*** CREDITS ***

Vsauce2
Twitter: https://twitter.com/VsauceTwo
Instagram: https://instagram.com/kevlieber
Facebook: https://www.facebook.com/VsauceTwo
TikTok: https://www.tiktok.com/@vsaucetwo
Talk Vsauce2 in The Create Unknown Discord: https://discord.gg/tcu
Vsauce2 on Reddit: https://www.reddit.com/r/vsauce2/

Hosted and Produced by Kevin Lieber
Twitter: https://twitter.com/kevinlieber
Podcast: https://www.youtube.com/thecreateunknown

Research and Writing by Matthew Tabor
https://twitter.com/TaborTCU

Editing by John Swan
https://www.youtube.com/channel/UCJuSltoYKrAUKnbYO5EMZ2A

Huge Thanks To Paula Lieber

Vsauce's Curiosity Box: https://www.curiositybox.com/

#science #scientist #history


guid: yt:video:qjGFD_7S7hg
title: The Insane Cult Leader Who Lived Inside The Earth
author: Vsauce2
url: https://www.youtube.com/watch?v=qjGFD_7S7hg
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/qjGFD_7S7hg?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Subscribe to Popular Science: https://www.youtube.com/@popularscience

Subscribe to Mind Blow:  https://www.youtube.com/@MindBlowOriginal

Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

As the 20th century approached, our understanding of the natural world and of the cosmos was increasing at a more rapid pace than any time in the history of science. We were building on our knowledge of asteroids, the discovery of Neptune, and understanding the transit of Venus, and science fiction like Jules Verne's "Journey to the Center of the Earth" was taking our imagination deep inside our own planet.

But one man rejected the long march of seemingly-irrefutable scientific progress. The cult leader Cyrus Teed was convinced that we weren't living amidst a complex solar system, and that we weren't on top of the Earth at all. Cyrus Teed thought that we were living inside the Earth.

Teed's Koreshan movement focused on the concept of a hollow earth, and he set out to prove scientifically that we were living on a concave surface inside of a giant hollow ball. From the religious awakenings of Upstate New York to Chicago to a swamp in Florida, Cyrus Teed gained converts who believed in his science and his religion. But did the rectilineator Teed built to conduct his painstaking measurements prove that we're really living inside, or did they just prove that Teed and his followers were insane?

#popularscience #science #education


guid: yt:video:bQWNKs4x5xk
title: The Lost Genius of Roald Dahl
author: Vsauce2
url: https://www.youtube.com/watch?v=bQWNKs4x5xk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/bQWNKs4x5xk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Let our sponsor BetterHelp connect you to a therapist who can support you - all from the comfort of your own home. Visit https://betterhelp.com/vsauce and enjoy a special 10% discount on your first month.

Everyone knows Roald Dahl’s stories, and several generations have grown up on Willy Wonka, Matilda, and more. But lurking behind the Oompa Loompas and the giant peaches is the life of a scientist, an inventor, and a medical pioneer so important that his work has saved thousands of lives worldwide -- and Dahl did his best to make sure you didn’t know it.

The bizarre life of Roald Dahl is a true story full of twists, turns, and tragedies. He survived his own traumatic brain injury in a World War II plane crash, and it might have done him a bit of good as a creator. But years later when his infant son was hit by a taxi, Roald harnessed his surprisingly deep medical and scientific knowledge to help create a cerebral valve that would benefit generations of children… all while keeping his own involvement quiet.

His most significant contribution to medicine may have come after that when his wife Patricia Neal suffered a series of strokes. Roald Dahl wasn’t a neurology expert, and he had no special expertise in brain injury or stroke recovery. What he did have was a creative mind, and the regimen he invented to rehabilitate Pat’s brain and body became the standard for our treatment of strokes.

Was Roald Dahl a fantastic artist, or was he a talented scientist? The answer is… yes. And that begs the question: is there even a difference?

#roalddahl #neuroscience #neurology


guid: yt:video:qHyvPpJtsMs
title: The Feral Child Tied To A Toilet For 13 Years
author: Vsauce2
url: https://www.youtube.com/watch?v=qHyvPpJtsMs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCqmugCqELzhIMNYnsjScXXw
enclosure_url: https://www.youtube.com/v/qHyvPpJtsMs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
[This is a censored re-upload because YouTube has once again targeted Vsauce2 and Age-Restricted the previous upload which essentially shadowbans it.] Let our sponsor BetterHelp connect you to a therapist who can support you - all from the comfort of your own home. Visit https://betterhelp.com/vsauce and enjoy a special 10% discount on your first month.

Support Vsauce2 on Patreon: https://www.patreon.com/Vsauce2

Genie Wiley was found in California in 1970, a feral child subjected to 13 years of horrors at the hands of her father -- and her tragic story blurs the line between research and true crime. It's part psychology, part biology, part linguistics... and all a chapter in the dark history of science.

Genie presented an incredible opportunity to study the limits of and potential for language acquisition at a time when Noam Chomsky's "Syntactic Structures" dominated linguistic debates. But was it even possible to help an abused girl and study her at the same time? That depends on who you ask -- but the result was limited scientific knowledge and a broken life.

FURTHER READING / VIEWING:

"Genie: A Scientific Tragedy" by Russ Rymer

NOVA: "Genie, The Secret of the Wild Child" (1994)

This video is for educational, artistic, and documentary purposes.

#psychology #weirdhistory #truecrimestories


guid: yt:video:YQnz7L6x068
title: Creator of Ghostty talks Zig over Go
author: ThePrimeTime
url: https://www.youtube.com/watch?v=YQnz7L6x068
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/YQnz7L6x068?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Thanks to the sponsor for today's video - Graphite!

Check out stacked PRs, code review tools and more: http://gt.dev/topshelf

0:00 - Intro
0:52 - CTO to Open Source
7:00 - Graphite Ad
8:10 - Future Of Ghostty
21:30 - How It Started
25:29 - Zig vs Rust
29:53 - Go’s Place In The Stack
34:28 - Managing Open Source 
42:42 - Motivation 
45:49 - AI
52:21 - Live Q&A

Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
-- Mitchell Hashimoto | https://x.com/mitchellh
-- TJ DeVries | https://x.com/teej_dv?lang=en

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen


guid: yt:video:EH12jHkQFQk
title: It's Really Just That Bad
author: ThePrimeTime
url: https://www.youtube.com/watch?v=EH12jHkQFQk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/EH12jHkQFQk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:_5fTdZ7sQf4
title: The Drama Just Keeps Getting Worse
author: ThePrimeTime
url: https://www.youtube.com/watch?v=_5fTdZ7sQf4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/_5fTdZ7sQf4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://techcrunch.com/2025/01/11/matt-mullenweg-deactivates-wordpress-accounts-of-contributors-planning-a-fork/
By: Paul Sawers | https://x.com/psawers

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:a2MDENSvzJk
title: Devin Is A Lie?
author: ThePrimeTime
url: https://www.youtube.com/watch?v=a2MDENSvzJk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/a2MDENSvzJk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://www.youtube.com/watch?v=PTxoawPHW6A
By: Re: Design | https://www.youtube.com/@redesignuxui

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:XPyKbPLGzFI
title: This Guy Really Did Something
author: ThePrimeTime
url: https://www.youtube.com/watch?v=XPyKbPLGzFI
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/XPyKbPLGzFI?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://pthorpe92.dev/intro/my-story/
By: Preston Thorpe

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:DBhTW9764rk
title: Why Are We Not Talking About This?
author: ThePrimeTime
url: https://www.youtube.com/watch?v=DBhTW9764rk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/DBhTW9764rk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Reviewed Video: https://youtu.be/pmtuMJDjh5A?si=ewqigFsU5KTpRdvx
Teej: https://youtube.com/@teej_dv

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

# LINKS
https://www.youtube.com/watch?v=pmtuMJDjh5A
By: TJ DeVries | https://www.youtube.com/@teej_dv

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:FINJ0zhdfQ0
title: Project Stargate - $500,000,000,000 For AI
author: ThePrimeTime
url: https://www.youtube.com/watch?v=FINJ0zhdfQ0
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/FINJ0zhdfQ0?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://x.com/OpenAI/status/1881830103858172059

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:aqimsB6Refs
title: Bun 1.2 Looks Good
author: ThePrimeTime
url: https://www.youtube.com/watch?v=aqimsB6Refs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/aqimsB6Refs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://www.youtube.com/watch?v=uSzffuqfJQk

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:GNHuJE_GARc
title: I Think I Love Deepseek R1
author: ThePrimeTime
url: https://www.youtube.com/watch?v=GNHuJE_GARc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/GNHuJE_GARc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://x.com/nathan_covey/status/1883881019356631214/photo/1
By: Nathan Covey | https://x.com/nathan_covey

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:cQNyYx2fZXw
title: AI Is Making You An Illiterate Programmer
author: ThePrimeTime
url: https://www.youtube.com/watch?v=cQNyYx2fZXw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/cQNyYx2fZXw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
https://nmn.gl/blog/ai-illiterate-programmers
By: https://x.com/namanyayg

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:tI8Z9snG2U0
title: 🚨🚨 Comparing Zig and Go🚨🚨
author: ThePrimeTime
url: https://www.youtube.com/watch?v=tI8Z9snG2U0
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUyeluBRhGPCW4rPe_UvBZQ
enclosure_url: https://www.youtube.com/v/tI8Z9snG2U0?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Twitch https://twitch.tv/ThePrimeagen
Discord https://discord.gg/ThePrimeagen

Become Backend Dev: https://boot.dev/prime
(plus i make courses for them)

This is also the best way to support me is to support yourself becoming a better backend engineer.  

### LINKS 
 -- LINKS HERE --

Great News?  Want me to research and create video????: https://www.reddit.com/r/ThePrimeagen

Kinesis Advantage 360: https://bit.ly/Prime-Kinesis

Get production ready SQLite with Turso: https://turso.tech/deeznuts


guid: yt:video:Fjyw5L5aQsQ
author: george hotz archive
url: https://www.youtube.com/watch?v=Fjyw5L5aQsQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/Fjyw5L5aQsQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
title:
George Hotz | Exploring | we bought a tenstorrent e150! | Grayskull™ e150 | Open source | Jim Keller

content:
Date of the stream 16 Mar 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://tenstorrent.com/cards/ (Grayskull™ e150 - Add to cart) - $799
- https://tenstorrent.com/setup/
- https://github.com/orgs/tenstorrent/repositories
- https://github.com/geohot/tt-twitch
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
00:00:00 intro
00:00:40 tenstorrent e150
00:02:40 AT&T, AMD, Qualcomm
00:04:07 Jim Keller, Tenstorrent, Open source
00:07:13 nvidia orin devkit, TRUFFLE–1
00:10:10 tinybox specs, nvidia 5090 rumor
00:11:05 pushing AMD, embracing open source
00:12:20 unboxing e150
00:13:55 interactions with AMD, lying
00:15:13 tenstorrent mega blower fan
00:23:10 fan loudness check
00:23:45 fanless, thermal protection
00:28:42 tenstorrent.com/setup, NDA
00:29:10 Alex
00:30:22 hardware installation
00:34:10 banjo.canonical.com
00:35:10 firmware installing broken
00:39:55 work life balance, Alex   
00:41:15 tt-smi, temperature
00:43:07 tenstorrent bounties
00:47:15 smoke test
00:49:45 buda
00:53:40 cloud is a scam, selling cards
00:55:20 import error
00:57:50 this is why tinygrad is going win
00:58:55 nix
00:59:25 docker, no dependencies
01:02:20 nvidia value, cuda
01:02:55 reproducible builds, getting rid of complexity, it just works
01:05:30 import error
01:06:40 the complexity
01:06:54 redis great software
01:08:22 missing jemalloc
01:11:00 key error BACKEND_ARCH_NAME
01:12:15 mysql, sqlite
01:14:40 docker encouragees
01:15:15 exploring tt-metal
01:17:45 PEP8, bad programmers, details
01:18:25 downloading multiple gigabytes
01:20:35 translating github comments
01:25:00 tt-buda
01:26:04 stop writing code like this
01:32:30 if you thought AMD is bad try tenstorrent card
01:32:55 tt-smi reset options, reset file, reset json
01:35:45 this is the opposite of how you do complexity
01:36:40 ordering food, folding phone
01:42:05 tt-metal
01:46:00 start saying what it is
01:48:30 HSA fail, making everything generic
01:51:20 tt_lib, tt_eager
01:52:00 py-buda, luwen
02:04:00 installing egg
02:10:00 tensor bob
02:13:20 devin
02:15:30 reading docs
02:17:40 pyrsistent
02:19:40 Jim stop, nobody wants 50% PyTorch
02:19:55 be proud of what the chip is and expose the chip for what it is
02:21:19 ttlib docs, chip info
02:23:10 no real company is going to buy this card, dojo, inference price per dollar
02:23:50 tinygrad in for 10 years
02:24:05 PyTorch trigger
02:31:10 what this is?
02:35:45 grayskull e150 number of cores
02:37:20 bad documentation
02:42:44 tenstorrent staff in the stream
03:00:25 not trusting C
03:05:02 Alex closing the door
03:11:50 hate coding in C
03:17:00 bad code trigger, memcpy
03:27:17 SFPU
03:34:15 doing math, 13+7=21
03:43:30 kernel APIs
03:47:50 this better than GPUs
04:02:25 opencl api bad concept
04:06:30 food
04:12:20 life magazine 1970
04:16:10 Alex, Groq $20k card, Groq open source 
04:20:05 brain backprop, small work units
04:20:39 nvidia full fabric memory
04:22:26 tenstorrent website bug 
04:24:07 keeping up with state of the art ML
04:25:10 AMD price advantage, mi300x
04:28:20 graph compiler should be generic
04:28:35 port tinygrad to tenstorrent
04:33:40 the bitter lesson
04:38:50 break
04:47:12 worry about correctness
04:48:25 thumbs up ai
04:48:50 tinygrad code for metal
05:09:00 host_api
05:11:00 Karen ai, devin, VCs, deep state
05:15:17 unitree humanoid, money printer
05:19:04 1971, gold
05:25:50 clang 14 install, VC investment scam
05:42:50 dispatcher kernel, 1971, zebu ep1
06:03:00 fake queuing, scheduling is the key, big scale
06:11:30 Groq demo, tt hardware, wormhole
06:29:25 software, endorsing tenstorrent, comma body
06:49:50 X9000 G2 Groq demo challenge

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:6fFUfyT-EyA
title: George Hotz | Exploring | finding exploits in AMD's GPU firmware | Giving up on AMD for the tinybox
author: george hotz archive
url: https://www.youtube.com/watch?v=6fFUfyT-EyA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/6fFUfyT-EyA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 21 Mar 2024.
from $1050 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/geohot/7900xtx
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
00:00:00 intro
00:00:40 blog post
00:02:00 open source driver, bugs
00:04:25 pre-orders, cheapETH, George jobs
00:06:30 no one use AMD? kernel, user space
00:08:25 not understanding, business platitudes, unpaid QA team
00:09:40 bugs are not in the driver, kernel driver does not talk to the hardware
00:12:45 GSP, MES
00:13:50 llvm amdgpu launching a kernel, firmware blobs
00:17:00 amd on mlperf
00:18:08 AMDGPU kernel driver change log, will never get better unless
00:19:05 Elon companies
00:19:20 people who succeed in companies do not care
00:21:15 believing wrong things, change, correcting
00:21:55 scaling comma.ai, throwing money at comma.ai, $1 mil per month
00:24:05 fundamentally correct, life wasted on wrong things
00:24:35 kernel dispatch, CP
00:26:08 technically wrong
00:27:49 deadlock, root causing
00:29:10 will never get better
00:30:40 props to AMD, fixing the issues
00:31:20 MES correct description
00:31:50 normal bug
00:32:40 oh god, appreciation for software development, horrifying solution, why is this a flag
00:33:40 drivers have been shit for 25 years
00:34:07 should be an if statement in the allocator not a flag
00:35:20 offer, downside risk, worries about bad PR
00:38:40 sony, suing someone, led by emotions
00:41:10 instinct, Nvidia generations, Apple monopoly
00:45:45 blackwell chip, RDNA 4, Dojo
00:48:50 tenstorrent, mlperf
00:50:45 turing completeness
00:51:00 Jim Keller
00:52:26 7900XTX firmware, Elon can execute
00:53:30 12xIntel Arc, Groq LPU scam demo, Nvidia king
00:55:00 fixing culture, qualcomm
00:57:05 working with George, Elon genius
00:58:44 JH7110, RK3588, qualcomm situation
01:00:25 oneplus folding phone money back
01:02:50 stress, clean ubuntu install
01:04:40 hsakmt debug level, business decisions
01:07:50 dynamic debug how to 
01:10:10 hip graph vs cuda graph
01:13:40 loading static libs with ctypes, libdrm
01:20:20 moving on
01:23:55 hsa_queue_create
01:25:20 GPU user spaces very complex
01:27:00 exploits
01:33:50 building tiny boxes, open source timeline 
01:37:20 user space crash
01:41:40 ctypes uint8_t pointer from address
01:48:30 random queue
01:55:10 fuzz things
01:55:35 teaching hacking, what is this thing
02:00:40 messages from the kernel, ubuntu rebuilding kernel
02:06:40 heven, are you a good person
02:09:10 unload, load, module, 
02:09:25 hacking 50% setting up your env, knowing a lot, binary search by hand
02:18:20 gpu smu mes, phoronix are legit, gfx1100
02:26:05 architecture
02:26:30 kernel driver, minimal all the way to the hardware
02:29:00 RDNA3 firmware architecture
02:32:18 Lana_Lux raid!
02:33:40 recap of the stream, driver not opensource
02:34:30 firmware closed source, signed
02:36:20 talking with AMD, unpaid QA team
02:37:05 work with the product, ordering food
02:39:40 MES support
02:40:20 by monday it's over, hacking is addictive 
02:44:20 it's not like qualcomm
02:46:20 what did AMD give, talking
02:52:15 Ghidra, food
03:11:44 verbose
03:24:30 size_bytes, ucode, assembler and disassembler
03:35:45 F32 disassembler, f32 microcode
03:43:10 technical info, Sam Altman
03:50:20 giving up, reverse engineering not sustainable
03:58:40 evil plot, un-paid QA team 
04:02:00 break
04:08:50 amd gpu, psp, dcn
04:17:00 interoperability, nvidia for commercial purposes
04:22:50 sas, ta, sos, amd vcn, sdma
04:29:40 secretive amd, imu gc, this is dumb
04:33:40 muted
04:50:00 build one module in linux kernel tree, why reboot
05:37:20 if we corrupt it
05:47:50 amd psp function, amd gpu bootloader
05:53:00 signature check, amdgpu disable dma debug
06:14:25 intel, business development
06:15:25 shill for comma, toyota
06:20:00 security model
06:26:10 tenstorrent, rdna3 emulator
06:34:00 break
06:41:40 7900XTX vs 4090 compute, nvidia firmware, market forces
06:50:30 INVALID_ARGUMENT, docs
07:09:00 ROCm does not work, hard decision, crypto miner
07:15:25 nvidia bugs, docs to drive gpu
07:47:10 message to AMD, amd stock, gpu market share, nvidia, elon musk
08:04:10 boeing, arm ai chip, google, jensen huang, sam altman

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:rUsx1b7rQ8Q
title: George Hotz | Exploring | sniffing NVIDIA's ioctls | open-gpu-kernel-modules | DEBUG | PTX | CUDA
author: george hotz archive
url: https://www.youtube.com/watch?v=rUsx1b7rQ8Q
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/rUsx1b7rQ8Q?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 23 Mar 2024.
from $1050 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/NVIDIA/open-gpu-kernel-modules
- https://github.com/geohot/cuda_ioctl_sniffer
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
- in progress

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:-iH5wvFnsKs
author: george hotz archive
url: https://www.youtube.com/watch?v=-iH5wvFnsKs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/-iH5wvFnsKs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
title:
George Hotz | Programming | ripping out all of AMD's userspace, AMDGPU ioctls | GPU memory | HSA KFD

content:
Date of the stream 23 Mar 2024.
from $1050 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/tinygrad/tinygrad
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
- in progress

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:BCnTXwhzzxA
title: George Hotz | Programming | writing a fuzzer and not getting triggered when the AMD GPU crashes UMR
author: george hotz archive
url: https://www.youtube.com/watch?v=BCnTXwhzzxA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/BCnTXwhzzxA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 24 Mar 2024.
from $1050 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://gitlab.freedesktop.org/tomstdenis/umr
- https://themaister.net/blog/2023/08/20/hardcore-vulkan-debugging-digging-deep-on-linux-amdgpu/
- https://github.com/tinygrad/tinygrad
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
- in progress

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:Y-0yZ1AHb0s
author: george hotz archive
url: https://www.youtube.com/watch?v=Y-0yZ1AHb0s
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/Y-0yZ1AHb0s?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
title:
George Hotz | Researching | documenting the AMD 7900XTX so we can understand why it crashes | RDNA 3

content:
Date of the stream 31 Mar 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/geohot/7900xtx
- https://github.com/tinygrad/tinygrad
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/)

Chapters:
00:00:00 intro
00:01:25 new KFD backend
00:03:50 never give up
00:05:20 tinybox
00:07:00 looking for comment
00:11:35 docs for 7900XTX
00:13:40 university attendance over time us
00:22:00 vscode markdown preview
00:31:10 signature solar, solaredge optimizers
00:45:45 solar per watt over time
00:50:50 github.com/geohot/7900xtx, tenstorrent software
00:58:20 ubuntu kernel build source don't use apt src
01:01:00 AMD processes, Instinct MI 300, testing in isolation, crashes
01:03:00 no CI for hardware
01:05:50 planning, handling George as PR problem
01:15:00 nvidia taking AMD talent
01:15:50 old instinct cards
01:17:00 test_sdma
01:34:00 firmware file, registers dump
01:37:55 all this docs might be wrong
01:39:30 drivers from AND will not get better
01:46:00 US government people
01:48:10 product engineering, operations, engineering mindset manipulating things not people
01:49:00 everybody who creates is an engineer, administrator not an engineer
01:49:30 boeing, outsourcing, operations keeping systems running
01:51:30 how do you get more gold, more fiat, bitcoin, people
01:54:00 proof of work to proof of stake ethereum
01:56:00 gold works
02:09:00 diversity is our strength
02:19:55 DRM debugging
02:24:19 AMD brutal reviews
02:28:40 4090 tracker
02:39:05 hardware resources
02:48:00 LSDMA, system DMA and other DMA
03:00:00 codenames, UMR
03:05:10 perplexity, searching, search engine
03:09:50 RDNA 3
03:28:50 compute unit
03:35:50 gpu hang, crash, piano
03:39:20 amd community forums
03:41:10 AMD release register reference 79000 XTX
03:42:40 George helping AMD
04:01:35 plum bonito gfx1100
04:03:15 RS64
04:09:55 AMD gpu mailing list
04:13:40 break, shower
04:24:50 should you buy 79000 XTX
04:25:35 AMD PR team, disparaging, George's experience with GPU
04:27:50 the modern consumer
04:30:00 open pilot CI, comma ai failure rate
04:52:50 radeon f32 processor
04:54:20 leak, leak is a public domain
04:58:50 XML dump of bonaire register docs
05:00:00 internet is under attack, remember when google worked
05:01:00 2014
05:06:00 free speech, hate speech, iq vs free speech absolutism
05:17:40 MEC, amdgpu microengine compute
05:46:50 how to power cycle pci device
05:50:15 AMD I want the MEC
06:24:10 error: object file empty git
06:27:25 docs for 79000 XTX overview
06:35:40 SDMA+RLC are F32, RS64
06:38:10 AMD source about register access
06:41:55 ibm rs64 32-bit
06:46:10 rs64 soft core
06:50:50 Alex, RDNA 4
06:53:40 reading about workload managers
06:55:30 the AMDGPU code base 
06:56:30 job offer to github.com/gnif
06:57:20 writing software, taping out chips
06:58:40 prediction on AMD high end GPUs
06:59:35 qualcomm reverse engineering
07:01:30 openmax, OMX
07:02:15 can people draw attention to this?
07:03:40 looking glass
07:05:35 internal AMD docs
07:06:40 tinygrad new driver, new style of driver, CommandQueue
07:07:20 $1000 to fix a reset of GPU for github.com/gnif

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:j7MRj4N2Cyk
title: George Hotz | Researching | same thing we do every weekend, documenting the AMD 7900XTX | Part 1
author: george hotz archive
url: https://www.youtube.com/watch?v=j7MRj4N2Cyk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/j7MRj4N2Cyk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 6 Apr 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://cs.unc.edu/~otternes/papers/rtns2021.pdf
- https://x.org/docs/AMD/old/R5xx_Acceleration_v1.2.pdf
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
00:00:00 intro
00:01:10 AMD open source announcement
00:01:50 AMD does not understand the spirit of open source
00:02:25 GPU quality, PR, praise AMD when they release source code
00:02:45 what will AMD open source?
00:03:45 AMD employees banned from discord
00:04:14 KFD architect AMD Felix Kuehling
00:06:00 PR is bad, comma marketing safety
00:07:40 the spirit of open source, GPU quality will make money long term
00:08:25 ghost locomotion, $217 million gone
00:08:50 business model
00:09:30 what companies get wrong today, influencing the narrative
00:10:30 truth, reality is reality
00:11:00 appreciate engaging on a technical level
00:11:30 internet lies, truth, being on your own
00:12:40 hacker manifesto, hacker culture eric raymond, hacker culture
00:13:50 responding to HN Hector Martin - marcan42, asahi linux
00:16:10 George Hotz security background
00:16:45 communication style, lone genius
00:17:20 response to 10 years sony story
00:18:18 political disagreement
00:19:25 hacker news doubt, marcan worked on asahi linux
00:20:30 lone geniuses, building on other people
00:21:25 Jürgen Schmidhuber credit, Yoshua Bengio, Geoffrey Hinton, Yann LeCun
00:22:25 infosec people, talented people giving up
00:23:15 never give up never surrender, some people are better than others
00:25:30 showing off in videos, depth in videos
00:26:10 Elon no ego, I want to be right but not at expense of being wrong
00:27:10 views, entertainer
00:28:00 hacker manifesto, getting mad at AMD
00:29:00 compounding successes, spacex success
00:29:45 Tesla FSD attitude, zen with GPUs
00:31:20 change log, not high quality
00:32:00 ghost autonomy, public domain
00:33:45 intellectual property
00:34:50 sonny bono copyright extension act
00:37:45 regression bug
00:41:30 computers don't feel pain
00:42:18 4 compute types, SDMA, COMPUTE_AQL, COMPUTE PM4
00:43:20 marcan hn, AMD comunication
00:44:15 comma ai safety model, fear uncertainty doubt
00:45:50 watch what I do not what I say, geohot github
00:46:40 most honest response to a hater
00:47:15 CP old term, personal attacks
00:50:10 tomcr00se soundcloud civil war
00:50:50 Elon test, AMD hardware issue
00:52:25 how hard is to change yourself, other people
00:52:40 HWE = hardware enablement, food
00:53:50 what we did so far on the stream
00:54:45 AMD released a tweet
00:56:10 death spiral sequence, search engine, logging-in
00:57:10 kagi, Apple, no more iPhone, search engine MacOS, arc browser, xz utils
01:02:20 launch a kernel with PM4 packets
01:02:55 roct-thunk-interface
01:08:20 want the world to be better, personal gain, mechanized slaves, hvac
01:10:30 PM4 vs AQL, crash info, PM4 might bypass all this garbage
01:12:50 ai alignment
01:15:00 bug identified correctly, not fixed
01:18:50 nvidia driver, umr, RS64
01:26:25 timeline for stable red tiny box, 20 conversions to green and conversions 2 to red
01:27:50 280 pre-orders, 40 cancellations
01:29:35 if we go to this level GPU will be stable, PM4
01:31:00 GPU-specific dispatch registers, quest for low level control stupid and contrary to all business objectives
01:33:00 has not crashed yet
01:40:00 Virtual Memory Identifiers (VMIDs)
01:43:00 exploring amd gpu scheduling details by experimenting with worst practices
01:45:00 downgrade firmware no crash, regression
01:53:15 PQ
01:56:40 amd global data share
02:02:40 how to dump this queue
02:13:00 favorite AMD employee is streaming
02:17:25 PQ, pipe queue, AI hallucination
02:19:59 PQ BASE, mac os x forwarding
02:32:45 gl x forwarding nvidia ubuntu 22.04
02:37:59 packet queue
02:42:55 ubuntu setup vnc, mac os x vnc client brew
02:47:55 control b stupid shortcut, control a
02:49:45 starting with computers today, if you are old it's over
02:54:30 vnc opengl
02:55:20 wayland, era of linux desktop, microsoft rdp
02:58:00 sdl2 x xquartz forwarding mac os x
03:01:20 launching gui for an hour
03:04:10 booting asahi linux macbook
03:07:10 sharing macbook screen
03:12:00 shower

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:Z04xTlLdZnc
author: george hotz archive
url: https://www.youtube.com/watch?v=Z04xTlLdZnc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/Z04xTlLdZnc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
title:
George Hotz | Reverse engineering | switching from AQL to PM4 to avoid bugs on the AMD 7900XTX Part2

content:
Date of the stream 6 Apr 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/geohot/7900xtx
- https://github.com/fail0verflow/radeon-tools
- https://github.com/NationalSecurityAgency/ghidra
- https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/notebooks/RISCV/RISCV_CARD.pdf
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
00:00:00 intro
00:01:50 meditation
00:04:10 questions, AQL packets, radeon southern islands
00:06:00 two code paths
00:10:10 amd vulkan, dispatch_indirect
00:18:30 packet queue = AQL packets, amdgpu eop
00:22:10 AQL_CONTROL
00:30:55 blog part 3
00:37:00 resnet training job to crash
00:40:00 DEBUG=2
00:43:00 getting rid of AQL
00:45:30 engineer wrote something specific and project manager changed the words
00:47:10 selected pipe, queue does not matter
00:48:10 different queues
00:50:15 PM4, PGM_RSRC2 
00:56:10 EVENT_WRITE.partial_flush comment
00:58:40 more testing of KFD, moving away from AQL
01:01:20 gpu_driver.cc
01:05:30 does someone want's to write PM4?
01:09:45 when I make the GPU
01:10:20 nvidia and amd very similar
01:10:50 firmware absolutely simple as possible, how easy is updating different tier of software
01:11:20 why AQL exists?
01:19:45 we got the crash
01:29:00 double banned, umr, smc bits read_smc
01:33:00 30% chance PM4 does not have bugs
01:33:40 rosetta stone style translation F32 and RS64
01:38:10 radeon_tools marcan
01:38:20 is AMD going to open source anything useful
01:40:40 ghost locomotion, argo ai
01:42:40 argo the next thing, can everyone stop, cleaning solution
01:44:30 can we all just be more honest
01:45:35 AMD NDA, infringing patents, 
01:52:15 being afraid of getting sued
01:55:30 DISPATCH_DIRECT packet
02:00:40 amd gpus codenames, fiji
02:02:55 linux-firmware license, not a lawyer
02:06:10 nvidia gsp license, cuda license no datacenter use
02:07:55 risk averseness of people
02:10:40 linux-firmware
02:20:40 rosetta stone, F32, RS64
02:37:00 launching specific kernel
02:40:40 first GPU to support AQL
02:46:50 NSA, Ghidra, IDA Pro, Russian tools
02:48:30 respect NSA github
02:48:50 NSA better at open source then AMD
02:49:14 NSA more open source than AMD
02:49:30 backdoors
02:54:20 drake rosetta stone song
02:57:30 credit marcan for writing the disassembler
03:15:45 binvis
03:19:30 fail0verflow radeon talk
03:39:25 F32
03:48:30 gfx1101
03:53:20 amd rs64
04:10:15 gfx rs64
04:17:55 python os lseek
04:23:15 amdgpu_regs, mmio
04:34:35 decompiling now
04:38:50 all the different addresses
04:42:30 dump_ip.c, upset writing C
04:48:25 c example mmap fd
04:51:18 read without advancing file pointer
05:03:20 bugs in the dispatch
05:20:25 frequency analysis on code
05:31:45 next 4 bytes are register
05:47:00 amd_emu_mode
05:57:35 we broke the gpu, what did we learn today?
06:00:05 I have given you the tools you need to solve the problem
06:05:40 switch to nvidia if you have AMD crashes
06:09:05 risc-v opcode groups
06:12:30 capstone risc-v disassembler
06:18:20 skip instructions, CS_ARCH_RISCV mode
06:22:20 bad at ghidra
06:23:30 don't spoil the risc-v
06:33:00 if labeled easier to read, launch instructions, almost just compile
06:33:55 figuring out the first instruction
06:38:30 load this register map
06:52:00 ghidra load map file
07:35:20 jump table that goes there, some CP function
07:54:25 cmd 3 packets pm4
08:05:00 it's cool that is risc-v
08:23:40 now we can know if AMD open sources anything real
08:29:50 I bet this did not support AQL
08:33:50 we need to stup
08:42:45 I have found why there is so many bugs in this
08:49:15 back in the days of bonaire
08:56:50 HSA was a marketing campaign
08:57:30 internet issues

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:R8uxmXmtOrk
title: George Hotz | Programming | tinygrad updates and fast MCTS search | tinygrad.org/#tinybox
author: george hotz archive
url: https://www.youtube.com/watch?v=R8uxmXmtOrk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/R8uxmXmtOrk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 21 Jul 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai
Live-stream chat added as Subtitles/CC - English (Twitch Chat) - at the bottom - Show Transcript

Source:
- https://github.com/tinygrad/tinygrad
- https://tenstorrent.com/hardware/tt-quietbox
- https://tinygrad.org/#tinybox
- http://www.incompleteideas.net/IncIdeas/BitterLesson.html
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:h0jT60MBsvc
title: George Hotz | Programming | toonygrad! a rewrite of the tinygrad middleware (1/n) | Hong Kong
author: george hotz archive
url: https://www.youtube.com/watch?v=h0jT60MBsvc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/h0jT60MBsvc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 7 Oct 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai & - https://tinygrad.org/#tinybox

Source:
- https://github.com/tinygrad/tinygrad
- https://tinygrad.org/#tinybox
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:dw7w9uUKht4
title: George Hotz | Talking | Just Chatting | tinygrad, starting on CLOUD=1 | Part 1
author: george hotz archive
url: https://www.youtube.com/watch?v=dw7w9uUKht4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/dw7w9uUKht4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 9 Oct 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai & - https://tinygrad.org/#tinybox

Source:
- https://github.com/tinygrad/tinygrad
- https://tinygrad.org/#tinybox
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:LJbUaciFdV8
title: George Hotz | Just Chatting | how to actually win? | tinygrad.org
author: george hotz archive
url: https://www.youtube.com/watch?v=LJbUaciFdV8
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/LJbUaciFdV8?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 14 Oct 2024.
from $1250 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai & - https://tinygrad.org/#tinybox

Source:
- https://github.com/tinygrad/toonygrad/blob/master/PLAN.md
- https://github.com/tinygrad/tinygrad
- https://tinygrad.org/#tinybox
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:Gm0t-kAsHuY
title: George Hotz | Programming | making tinygrad CLOUD=1 fast (even from Hong Kong!) | Good Vibes :)
author: george hotz archive
url: https://www.youtube.com/watch?v=Gm0t-kAsHuY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/Gm0t-kAsHuY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 11 Nov 2024.
from $1150 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai & - https://tinygrad.org/#tinybox

Source:
- https://github.com/tinygrad/toonygrad/blob/master/PLAN.md
- https://github.com/tinygrad/tinygrad
- https://tinygrad.org/#tinybox
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:YYD3aZatWRo
title: George Hotz | Gaming | factorio space age "speedrun" | tinygrad.org/#tinybox
author: george hotz archive
url: https://www.youtube.com/watch?v=YYD3aZatWRo
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCwgKmJM4ZJQRJ-U5NjvR2dg
enclosure_url: https://www.youtube.com/v/YYD3aZatWRo?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Date of the stream 06 Dec 2024.
from $1150 buy https://comma.ai/shop/comma-3x & best ADAS system in the world https://openpilot.comma.ai & - https://tinygrad.org/#tinybox

Source:
- https://github.com/tinygrad/toonygrad/blob/master/PLAN.md
- https://github.com/tinygrad/tinygrad
- https://tinygrad.org/#tinybox
Follow for notifications:
- https://twitch.tv/georgehotz
Support George:
- https://twitch.tv/subs/georgehotz
Pre-order tinybox:
- https://buy.stripe.com/5kAaGL6lk9uX9nW144 (https://tinygrad.org/#tinybox)

Chapters:
TBD

Official George Hotz communication channels:
- https://geohot.com
- https://twitter.com/realGeorgeHotz
- https://instagram.com/georgehotz
- https://tinygrad.org
- https://geohot.github.io/blog
- https://github.com/geohot

We archive George Hotz and comma.ai videos for fun.
Follow for notifications:  
- https://twitter.com/geohotarchive

Thank you for reading and using the SHOW MORE button.
We hope you enjoy watching George's videos as much as we do.
See you at the next video.


guid: yt:video:kjhH48y4NEg
title: How I Turned HTML Into An Actual Programming Language
author: icitry
url: https://www.youtube.com/watch?v=kjhH48y4NEg
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/kjhH48y4NEg?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I’m tired of everyone laughing at me for calling myself an HTML programmer. I’m sure many are in the same boat as me, you included - don’t try to deny it. 

So I decided to show the beauty of this complex language, by adding those boring bits of so-called "essential building blocks for a valid programming language", making use of Svelte Kit and the all-powerful Python language and its well-known flexibility.

I'm sure this will serve as a turning point in the evolution of the entire industry. Perchance.

Github repo: https://github.com/icitry/HTMLAsAProgrammingLanguage


guid: yt:video:uME9wZ_Ikkc
title: I've Created A Hidden Reddit Feature So I Can Procrastinate In Peace
author: icitry
url: https://www.youtube.com/watch?v=uME9wZ_Ikkc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/uME9wZ_Ikkc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Have you ever wanted to slack off at work and mindlessly scroll through Reddit or some other mind numbing entertainment platform, but were too afraid your boss would catch you in the act?

Join me in creating a little helper in disguising our dissociative escapades – namely creating an extension that would allow the toggling between the classic Reddit interface and that of Microsoft Outlook.  

By the way, it just so happened I picked these two as the central figures, but I think this video should help in creating similar pairings, as I have covered pretty much all the important aspects of such a task.

Github repo: https://github.com/icitry/DisguisingRedditAsOutlook

If you wanna check it out, after getting the source files from the repo, you'll have to do this, depending on the browser (these are the ones I worked with, there's definitely more):

- Chrome:
1. Navigate to chrome://extensions.
2. Tick the "Developer mode" toggle (top right).
3. Press the "Load Unpacked" button (top left).
4. Select the "src" directory in which you have the source files (has the manifest.json file).

- Firefox:
1. Navigate to about:debugging#/runtime/this-firefox.
2. Press the "Load Temporary Add-on" button.
3. Select the "src" directory in which you have the source files (has the manifest.json file).


guid: yt:video:wsvnUlfUKlY
title: Turning YouTube Into Google Drive So I Don't Have To Pay For Storage
author: icitry
url: https://www.youtube.com/watch?v=wsvnUlfUKlY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/wsvnUlfUKlY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I'm sure by this point nobody can manage with that measly 15 gigs default limit on Google Drive. And I'm even more sure nobody is willing to donate their hard-earned cash to the Google overlords, myself included.

So I came up with the idea of using this seemingly unlimited Cloud Storage Service masterfully disguised as a video sharing website to remotely store whatever files my heart desires at virtually  no cost (except for my sanity).

Kick back and enjoy the ride, and make sure you don't snitch, cuz if they're coming for me, I'm taking you as well (this is a better Roko's basilisk dare I say).

Also, special thanks to Github user karaketir16, as when I was researching how to implement the encoder and decoder I did as any programmer would and took inspiration from his work.

Github repo: As to not get smitten by the YouTube overlords due to the potentially malicious nature of the project, the source code will not be available.


guid: yt:video:P0JC640XRO8
title: How I Created An AI Chat Bot That Uses Memes
author: icitry
url: https://www.youtube.com/watch?v=P0JC640XRO8
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/P0JC640XRO8?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I’m sure we all have at least one friend we can consider a living Database of Memes, ready for whatever life, or you, may throw at them. Quite the fascinating beings they are, and certainly worth studying, and if lucky, maybe even replicate, to a certain degree. 

And what better way to replicate them if not by using Machine Learning techniques to rival AI giants like ChatGPT, Bing Copilot or Google Bard (even Grok, if you care about that).

Join me as I try to create a full stack Empathetic Chat Bot app that will make it seem as if you're talking to a real human (debatable) behind the screen.

Github repo: https://github.com/icitry/EmpatheticChatBot


guid: yt:video:WO_g73k7DoM
title: Creating Impact Frames Programmatically With Python
author: icitry
url: https://www.youtube.com/watch?v=WO_g73k7DoM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/WO_g73k7DoM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
The often-unsung heroes of the animation medium - Impact Frames - are something I’ve always taken an interest in. And to better my understanding of them while involving my other interest – programming, I decided to try my hand at auto generating impact frames programmatically, as well as automatically finding the best locations to insert them in any provided clip (and I mean ANY kind of clip). 

Using Python and OpenCV for image processing, motion detection and managing of videos, I embark on a brand new adventure, trying to unravel the mysteries of such an underrated technique, trying to shine light upon it - with a classic twist, of course.

Github repo: https://github.com/icitry/ImpactFramesGenerator

Anime used in the intro sequence, as they appear:

Jujutsu Kaisen
Arcane
One Piece
Fire Force
One Punch Man
My Hero Academia
One Piece (2)
One Punch Man (2)
One Piece (3)
Mob Psycho 100
Fire Force (2)
My Hero Academia (2)
Fire Force (3)
Demon Slayer
My Hero Academia (3)


guid: yt:video:rb8kE-e2FXs
title: Running Code On Paper Using Just My Phone's Camera
author: icitry
url: https://www.youtube.com/watch?v=rb8kE-e2FXs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/rb8kE-e2FXs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I hereby bring forth the weapon of choice in the fight against AI – a Paper Compiler, as in a compiler that runs any code using only your handwriting on piece of paper.

Watch as, making use of technologies ranging from OCR (Optical Character Recognition) models, to Code Execution Systems and various brand new, shiny and interesting solutions, I create an app (using Flutter.. ) that allows me to take photos of a piece of code, optionally its input, and get in return the result of the code's execution, formatted using my very own handwriting (in an almost ideal manner - cope).

The Github repo: https://github.com/icitry/PaperCompiler


guid: yt:video:9a_O3QHLajw
title: Can I Create Video Games Using SQL? (No Game Engine)
author: icitry
url: https://www.youtube.com/watch?v=9a_O3QHLajw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/9a_O3QHLajw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Leaving all the other contenders - Unreal, Unity, Godot, GameMaker and many more - in the dust, I bring forth the strongest game development toolkit known to man - SQL.

Taking advantage of all the features this tool offers, I developed a fully functional Snake Game implementation, which runs on a remote database, to which anyone can connect, play (or watch), and marvel at the future of video games and their development.

Making use of PostgreSQL and a couple of really interesting options it has to offer, along with some of my beloved Python, I managed to create a fully interchangeble/interoperational architecture, to make this as customizable and modular as possible.

Link to the Github repo: https://github.com/icitry/SqlGameEngine


guid: yt:video:CYNpdmgwNTM
title: Can I Run Youtube Entirely From My Terminal? (No Browser)
author: icitry
url: https://www.youtube.com/watch?v=CYNpdmgwNTM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/CYNpdmgwNTM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
All of us have probably experienced the horrors beyond human comprehension that come with a classic Youtube session, so what do you say if, by taking this nigh infinite potential of the platform, while getting rid of all the fluff, we use it in the way it’s always been intended – running the entire thing from your terminal, no fancy useless UI, no fancy useless features and even no fancy useless graphics.

Watch as, by combining the powers of the official Youtube API, the ever-dependable Python and the ingenuity (ahem) of yours truly, I try to get the entirety of the Youtube experience running in a terminal, in such a way that no matter the environment, you'll get to experience the platform in its most adequate form.

Link to the repo: https://github.com/icitry/YoutubeCLI


guid: yt:video:7viwRDHBrqE
title: Can You Play Pac-Man Directly On Its Own Source Code?
author: icitry
url: https://www.youtube.com/watch?v=7viwRDHBrqE
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/7viwRDHBrqE?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Join me as I create a Quine Game Engine, which allows you to develop games as you would do it normally, except using APIs developed by yours truly, and compiling them using a custom tool that converts your beautiful creations into their most condensed form, to be enjoyed by everyone.
By making use of different techniques and technologies, like the C Language, JavaScript, Rollup.js, Terser, various optimization I attempt to recreate PacMan (the game) in its entirety and have it run as a Quine on its own source code.

Link to the repo: https://github.com/icitry/QuineGameEngine


guid: yt:video:b_WGoPaNPMY
title: I Remade YouTube From Scratch Using Just Bash
author: icitry
url: https://www.youtube.com/watch?v=b_WGoPaNPMY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UC8DntJ-sBtgC-jA0yEjxqjw
enclosure_url: https://www.youtube.com/v/b_WGoPaNPMY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I have decided that, in an effort of making the world know that Bash is still everything you need in this day and age, to remake YouTube from scratch using only that. That's right, from the Back-End to the Front-End, from the storage to the retrieval of files, including the actual process of transmitting data, I decided to implement everything a Full Stack app needs without allowing myself to step outside of the Bash bubble, no exceptions.

So, do you still think you need fancy frameworks like Django, Spring, React, Angular and many others that have burdened the web development sphere, when the proverbial golden goose is right there?

Link to the repo: https://github.com/icitry/BashTube


guid: yt:video:Gfx7e8WQKCk
title: Is Jai Ready for Production?
author: Tsoding Daily
url: https://www.youtube.com/watch?v=Gfx7e8WQKCk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/Gfx7e8WQKCk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Wallpapers: https://penger.city/wallpapers/

References:
- https://github.com/tsoding/jaibreak
- https://github.com/tsoding/wabt-wasm64232
- https://github.com/wingo/walloc
- https://github.com/tsoding/bfjit
- https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
- https://github.com/tsoding/zozlib.js
- Source Code: https://github.com/tsoding/infinite-pong-jai-wasm64

Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9 
- Pay for my VPS: https://zap-hosting.com/en/shop/donation/2038e94867b5e65cab2e72abf8ad956c/


guid: yt:video:D7iQ7LvI4vg
title: You Don't Need Text Editor - Just Use My ChatBot
author: Tsoding Daily
url: https://www.youtube.com/watch?v=D7iQ7LvI4vg
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/D7iQ7LvI4vg?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

References:
- https://github.com/tsoding/gatekeeper
- https://www.gnu.org/software/ed/
- https://gitlab.com/tsoding/bex
- https://github.com/tsoding/tula

Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9 
- Monero: 47WtJDPwdWCFCRDkobFPV4NoesPg8zToj3WSci8FxJRXMQF9G4UBngUSTiQEX5wWWLfWs3D67tR9gbANYfxoTaZsRyUrEkC


guid: yt:video:WpepPeOl3DI
title: Prequel to C3 nobody expected
author: Tsoding Daily
url: https://www.youtube.com/watch?v=WpepPeOl3DI
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/WpepPeOl3DI?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

References:
- C3 review: https://www.youtube.com/watch?v=Qzw1m7PweXs
- http://c2lang.org/
- https://c3-lang.org/
- https://gitlab.com/tsoding/porth
- https://github.com/tsoding/olive.c
- Hare review: https://www.youtube.com/watch?v=2E3E_Rh3mvw
- QBE review: https://www.youtube.com/watch?v=JTjNoejn4iA

Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9 
- XMR: 47WtJDPwdWCFCRDkobFPV4NoesPg8zToj3WSci8FxJRXMQF9G4UBngUSTiQEX5wWWLfWs3D67tR9gbANYfxoTaZsRyUrEkC


guid: yt:video:sNHzizPu7yQ
title: I made Futures from scratch
author: Tsoding Daily
url: https://www.youtube.com/watch?v=sNHzizPu7yQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/sNHzizPu7yQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Related playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VZ08cYW6yqNTWLKqLssw0nm
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYwdrsI_O-7wpo-_MMIdeX8
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VbieqjlUJWlqPDfnQAIlExO
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0Vatv6hIDGH2ZPOfoNpm00Cc

References:
- https://c3-lang.org/
- https://github.com/tsoding/panim
- https://github.com/tsoding/c3fut

Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9 
- XMR: 47WtJDPwdWCFCRDkobFPV4NoesPg8zToj3WSci8FxJRXMQF9G4UBngUSTiQEX5wWWLfWs3D67tR9gbANYfxoTaZsRyUrEkC


guid: yt:video:7z7tdqxn3m4
title: Creator of C3 improves the Lang Live as I use it
author: Tsoding Daily
url: https://www.youtube.com/watch?v=7z7tdqxn3m4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/7z7tdqxn3m4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Related Playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYH2HouIXMjFFuz7G1FrXiB
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0Vatv6hIDGH2ZPOfoNpm00Cc

Chapters:
- 00:00:00 - Intro
- 00:00:30 - Session Start

References:
- Source Code: https://github.com/tsoding/panim
- Panim Playlist: https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYH2HouIXMjFFuz7G1FrXiB
- Futures in C3: https://github.com/tsoding/c3fut
- Futures in C3 video: https://www.youtube.com/watch?v=sNHzizPu7yQ
- nob.h: https://github.com/tsoding/nob.h

Support:
- BTC: bc1qj820dmeazpeq5pjn89mlh9lhws7ghs9v34x9v9 
- XMR: 47WtJDPwdWCFCRDkobFPV4NoesPg8zToj3WSci8FxJRXMQF9G4UBngUSTiQEX5wWWLfWs3D67tR9gbANYfxoTaZsRyUrEkC


guid: yt:video:IGv5WYYmyfo
title: Async vs Multithreading
author: Tsoding Daily
url: https://www.youtube.com/watch?v=IGv5WYYmyfo
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/IGv5WYYmyfo?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Offline

Related playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VZ08cYW6yqNTWLKqLssw0nm
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYwdrsI_O-7wpo-_MMIdeX8
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VbieqjlUJWlqPDfnQAIlExO
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0Vatv6hIDGH2ZPOfoNpm00Cc

Chapters:
- 00:00:00 - Intro
- 00:00:44 - Session Start

References:
- Futures in C3: https://github.com/tsoding/c3fut
- WebSockets in C3: https://github.com/tsoding/c3ws

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:eEHqCZpYtOE
title: What do you need select/poll/epoll for
author: Tsoding Daily
url: https://www.youtube.com/watch?v=eEHqCZpYtOE
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/eEHqCZpYtOE?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Related playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VZ08cYW6yqNTWLKqLssw0nm
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYwdrsI_O-7wpo-_MMIdeX8
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VbieqjlUJWlqPDfnQAIlExO
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0Vatv6hIDGH2ZPOfoNpm00Cc

Chapters:
- 00:00:00 - Intro
- 00:00:48 - Session Start

References:
- Futures in C3: https://github.com/tsoding/c3fut
- WebSockets in C3: https://github.com/tsoding/c3ws

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:z1joHmzpoAc
title: This Library Turns C into Go
author: Tsoding Daily
url: https://www.youtube.com/watch?v=z1joHmzpoAc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/z1joHmzpoAc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Chapters:
- 00:00:00 - Intro
- 00:00:30 - Session Start

References:
- https://libmill.org/
- https://github.com/tsoding/c3fut
- https://github.com/tsoding/c3ws
- Sequel to mill: https://libdill.org/

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:hzjBdIJ9Ycs
title: Forget C - Assembly is All You Need
author: Tsoding Daily
url: https://www.youtube.com/watch?v=hzjBdIJ9Ycs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/hzjBdIJ9Ycs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Chapters:
- 00:00:00 - Intro
- 00:00:32 - Session Start

References:
- https://flatassembler.net/
- https://github.com/tgrysztar/fasm
- https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
- https://github.com/rexim/dotfiles
- https://github.com/nakst/gf
- https://menuetos.net/
- https://gitlab.com/tsoding/porth

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:sYSP_elDdZw
title: I made Coroutines from scratch
author: Tsoding Daily
url: https://www.youtube.com/watch?v=sYSP_elDdZw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/sYSP_elDdZw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Related Playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYkIVqDPCa63XiFA-ycqmOe

Chapters:
- 00:00:00 - Intro
- 00:01:11 - Session Start

References:
- https://github.com/tsoding/c3fut
- https://libmill.org/
- libmill stream: https://www.youtube.com/watch?v=z1joHmzpoAc
- https://www.musl-libc.org/
- assembly stream: https://www.youtube.com/watch?v=hzjBdIJ9Ycs
- https://github.com/tsoding/pinpog
- https://100r.co/site/uxn.html
- https://github.com/tsoding/good_training_language

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:jda3wgZxlgA
title: The Jai situation is insane!
author: Tsoding Daily
url: https://www.youtube.com/watch?v=jda3wgZxlgA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/jda3wgZxlgA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

References:
- https://github.com/tsoding/jaibreak
- https://tsoding.github.io/jaibreak/
- https://github.com/tsoding/wabt-wasm64232
- https://github.com/tsoding/infinite-pong-jai-wasm64
- https://surma.dev/things/c-to-webassembly/

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:aKk_r9ZwXQw
title: Compiling Should NOT be This Slow
author: Tsoding Daily
url: https://www.youtube.com/watch?v=aKk_r9ZwXQw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/aKk_r9ZwXQw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Chapters:
- 00:00:00 - Intro
- 00:00:45 - Session Start

References:
- https://yasserarg.com/tb
- https://github.com/RealNeGate/Cuik
- https://gist.github.com/rexim/2a6c45f981bfa5e6041f7946e6a70be3

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:6WhEZ0ruzVU
title: I switched from ASSEMBLY to C and it made my code better...
author: Tsoding Daily
url: https://www.youtube.com/watch?v=6WhEZ0ruzVU
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/6WhEZ0ruzVU?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

Related Playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYkIVqDPCa63XiFA-ycqmOe

Chapters:
- 00:00:00 - Intro
- 00:00:51 - Session start

References:
- https://github.com/tsoding/coroutines
- https://github.com/tsoding/c3fut
- https://github.com/tsoding/c3ws
- https://libmill.org/
- https://nvd.nist.gov/vuln/detail/CVE-2025-0395

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:Z8znH5Grz7I
title: I tried Ninja Build Tool and it changed me...
author: Tsoding Daily
url: https://www.youtube.com/watch?v=Z8znH5Grz7I
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/Z8znH5Grz7I?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat

References:
- https://www.youtube.com/watch?v=aKk_r9ZwXQw
- https://ninja-build.org/

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:jwb7SmyGr3A
title: My Journey is Finally Over - I know Network Programming
author: Tsoding Daily
url: https://www.youtube.com/watch?v=jwb7SmyGr3A
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCrqM0Ym_NbK1fqeQG2VIohg
enclosure_url: https://www.youtube.com/v/jwb7SmyGr3A?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Streamed Offline

Related Playlists:
- https://www.youtube.com/playlist?list=PLpM-Dvs8t0VYkIVqDPCa63XiFA-ycqmOe

Chapters:
- 00:00:00 - Intro
- 00:00:23 - Session Start

References:
- Tsoding - Coroutines - https://github.com/tsoding/coroutines
- Tsoding - Futures in C3 - https://github.com/tsoding/c3fut
- Tsoding Daily - What do you need select/poll/epoll for - https://www.youtube.com/watch?v=eEHqCZpYtOE
- https://c3-lang.org/
- https://www.youtube.com/watch?v=sZ8GJ1TiMdk
- https://raw.githubusercontent.com/nothings/stb/refs/heads/master/stb_ds.h

Support:
- https://github.com/tsoding/donate#support-tsoding


guid: yt:video:TO0Tx3w5abQ
title: Why I use Wave Function Collapse to create levels for my game
author: jdh
url: https://www.youtube.com/watch?v=TO0Tx3w5abQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/TO0Tx3w5abQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
this was so much work i'm about to (wave function) collapse

sorry I used the terms "element", "cell", and "pixel" interchangeably :c
they all mean the same thing!

SEE THE CODE (utilities, etc. coming soon!)
https://gist.github.com/jdah/ad997b858513a278426f8d91317115b9

Oskar Stålberg's visualization tool:
https://oskarstalberg.com/game/wave/wave.html

Thanks to Maxim Gumin for the original implementation of WFC:
https://github.com/mxgmn/WaveFunctionCollapse

TWITTER: https://twitter.com/jdah__
PATREON: https://www.patreon.com/jdah
GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://cppreference.com/
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com

0:00 Wave Function Collapse
3:29 Code
12:16 Demo
13:16 Extras!


guid: yt:video:ieqYtIMIsJ8
title: Programming player jump mechanics & more (LIVE GAMEDEV)
author: jdh
url: https://www.youtube.com/watch?v=ieqYtIMIsJ8
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/ieqYtIMIsJ8?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
code code code

TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://cppreference.com/
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com


guid: yt:video:aJt2POa9oCM
title: I added reflection to C++ just to make my game work.
author: jdh
url: https://www.youtube.com/watch?v=aJt2POa9oCM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/aJt2POa9oCM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
"it will all be worth it", i tell myself after fixing the 8th of 20 broken tests. 

CODE: https://github.com/jdah/archimedes

TWITTER: https://twitter.com/jdah__
PATREON: https://www.patreon.com/jdah
GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://cppreference.com/
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com

0:00 Intro
0:36 The Ideal
3:18 Plans A to D
5:27 Plan E
11:40 Saving the game
14:30 Other new things


guid: yt:video:GhTAoilsFUs
title: How NOT to make a game from scratch
author: jdh
url: https://www.youtube.com/watch?v=GhTAoilsFUs
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/GhTAoilsFUs?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
a different kind of video this time

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__

* Jonathan Blow - Truth in Game Design: https://www.youtube.com/watch?v=C5FUtrmO7gI
* Stream clip: https://www.youtube.com/watch?v=w7W3xM2tzRA

GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

0:00 Intro
0:14 What went wrong?
1:25 Prototyping
2:12 Mechanics
3:05 Design comes first
4:16 Simplicity
5:36 Gameplay over graphics
6:40 Where to go from here
7:41 Patreon Launch & Outro


guid: yt:video:fSjc8vLMg8c
title: Programming a first person shooter from scratch like it's 1995
author: jdh
url: https://www.youtube.com/watch?v=fSjc8vLMg8c
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/fSjc8vLMg8c?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
3D like you've never seen it before!

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__

CODE: https://github.com/jdah/doomenstein-3d

GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

RESOURCES:
* DOOM Game Engine Black Book: https://fabiensanglard.net/gebbdoom/
* @Bisqwit 's video: https://www.youtube.com/watch?v=HQYsFshbkYw
* Fabien Sanglard's "Build Engine Internals": https://fabiensanglard.net/duke3d/build_engine_internals.php
* DOOM source code: https://github.com/id-Software/DOOM
* The DOOM wiki: https://doomwiki.org/

0:00 Intro
0:47 Why?
1:21 Wolfenstein 3D-style
2:55 DOOM-style
9:50 Level Editor
14:35 Proof of Concept
15:53 Outro & Thanks


guid: yt:video:jlRdSdHD3Wg
title: Programming portals for my DOOM-style FPS
author: jdh
url: https://www.youtube.com/watch?v=jlRdSdHD3Wg
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/jlRdSdHD3Wg?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
obsolete C programmer copies valve (15 years too late)

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__

C LIVE RELOADING: https://github.com/jdah/reloadhost
EXAMPLE SOFTWARE RENDERER: https://github.com/jdah/doomenstein-3d

GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

RESOURCES:
* Portals in OpenGL: https://github.com/ThomasRinsma/opengl-game-test
* @SebastianLague 's video on portals (in Unity): https://www.youtube.com/watch?v=cWpFZbjtSQg
* DOOM Game Engine Black Book: https://fabiensanglard.net/gebbdoom/
* DOOM source code: https://github.com/id-Software/DOOM
* The DOOM wiki: https://doomwiki.org/

0:00 Intro
0:15 Software Renderer
6:40 "Real" 3D
15:00 Extras
16:30 Outro & Thanks


guid: yt:video:67b18ixEomc
title: cozy saturday night gamedev in C
author: jdh
url: https://www.youtube.com/watch?v=67b18ixEomc
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/67b18ixEomc?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
code code code code code

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__
C LIVE RELOADING: https://github.com/jdah/reloadhost
EXAMPLE SOFTWARE RENDERER: https://github.com/jdah/doomenstein-3d
GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com


guid: yt:video:KyhrqbfEgfA
title: 4 Months of Game Programming With My Own Engine
author: jdh
url: https://www.youtube.com/watch?v=KyhrqbfEgfA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/KyhrqbfEgfA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
next time its 5 months

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__

DOOM RENDERER CODE: https://github.com/jdah/doomenstein-3d

GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

RESOURCES:
* https://learnopengl.com 
* DOOM Game Engine Black Book: https://fabiensanglard.net/gebbdoom/
* Michael Abrash's "Graphics Programming Black Book"


guid: yt:video:b5ovU9xeQ7c
title: Programming a multiplayer game from scratch in 7 DAYS
author: jdh
url: https://www.youtube.com/watch?v=b5ovU9xeQ7c
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/b5ovU9xeQ7c?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Grab a free 30 day trial and 20% off an annual plan: https://brilliant.org/jdh/

time for some wizardry

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__

*** itch link coming soon ! ***

BASIC NETWORK DEMO: https://gist.github.com/jdah/08eb80c74b13176027c08cbf48b239c9
MACRO WIZARDRY: https://gist.github.com/jdah/1ae0048faa2c627f7f5cb1b68f7a2c02

THINSG MENTIONED IN THE VIDEO
* networking articles: https://www.gabrielgambetta.com/entity-interpolation.html
* enter the gungeon levels: https://www.boristhebrave.com/2019/07/28/dungeon-generation-in-enter-the-gungeon/

GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

RESOURCES:
* OpenGL: https://learnopengl.com

OTHER VIDEOS:
Minecraft in 48 hours - https://www.youtube.com/watch?v=4O0_-1NaWnY
Building my own graphics card - https://www.youtube.com/watch?v=OW1EmG7b4DU
Building a DOOM-style rendering engine - https://www.youtube.com/watch?v=fSjc8vLMg8c
Tetris OS - https://www.youtube.com/watch?v=FaILnmUYS_U

0:00 Intro
0:20 One week
16:00 Extras
17:11 Outro & Thanks


guid: yt:video:cCvjaC_cZ0k
title: i am learning odin (live!)
author: jdh
url: https://www.youtube.com/watch?v=cCvjaC_cZ0k
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/cCvjaC_cZ0k?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
odin odin odin odin odin

TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: neovim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com


guid: yt:video:ajbYYgbDXGk
title: making a game in zig (i have never used zig) LIVE!
author: jdh
url: https://www.youtube.com/watch?v=ajbYYgbDXGk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/ajbYYgbDXGk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
zig zig zig zig zig zig zig

TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: neovim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com


guid: yt:video:k2JwpQ2ICJk
title: making a game in 48 hours LIVE!
author: jdh
url: https://www.youtube.com/watch?v=k2JwpQ2ICJk
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/k2JwpQ2ICJk?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
make game (very fast)

LUDUM DARE: https://ludumdare.com

TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: neovim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox
RESOURCES:
  http://learnopengl.com
  http://opengl-tutorial.org
  http://shadertoy.com
  http://stackoverflow.com


guid: yt:video:PcMua73C_94
title: I redesigned my game
author: jdh
url: https://www.youtube.com/watch?v=PcMua73C_94
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/PcMua73C_94?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
check out https://brilliant.org/jdh for a free 30-day trial and a 20% discount on an annual premium subscription to Brilliant!

i think the youtube compression is gonna ruin this one

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: NeoVim
CONFIGS: https://github.com/jdah/dotfiles
THEME: gruvbox

GAMES I MENTIONED:
Devil Daggers: https://store.steampowered.com/app/422970/Devil_Daggers/
Post Void: https://store.steampowered.com/app/1285670/Post_Void/
Eclipsium: https://store.steampowered.com/app/2419670/Eclipsium/

RESOURCES:
* sokol: https://github.com/floooh/sokol
* @SebastianLague 's video on fluid simulation: https://www.youtube.com/watch?v=rSKMYc1CQHE
* article on fluid simulation: https://lucasschuermann.com/writing/implementing-sph-in-2d
* all that noise: https://thebookofshaders.com/13/
* markov chains: https://benhoyt.com/writings/markov-chain/


guid: yt:video:rgIRsSZ4dlA
title: i made a little christmas game 🎄
author: jdh
url: https://www.youtube.com/watch?v=rgIRsSZ4dlA
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCUzQJ3JBuQ9w-po4TXRJHiA
enclosure_url: https://www.youtube.com/v/rgIRsSZ4dlA?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
TRY IT OUT: https://jdah.itch.io/elf

PATREON: https://www.patreon.com/jdah
TWITTER: https://twitter.com/jdah__
GITHUB: https://github.com/jdah
EDITOR: neovim
CONFIGS: https://github.com/jdah/dotfiles
THEME: kanagawa


guid: yt:video:AHYNxpqKqwo
title: The RS-232 protocol
author: Ben Eater
url: https://www.youtube.com/watch?v=AHYNxpqKqwo
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/AHYNxpqKqwo?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
This video explores the electrical and timing characteristics of the RS-232 protocol.

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, Alex Black, Andrew Van Gerpen, anula, Ben, Ben Cochran, Ben Kamens, Ben Williams, Bill Cooksey, Binh Tran, Bradley Stach, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chaitanya Bhatt, Chris Lajoie, Chris Sachs, criis, Daniel Jeppsson, Daniel Pink, Daniel Tang, Dave Burley, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Schubert, Dilip Gowda, Dušan Dželebdžić, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Thayer, Eveli László, Florian Rian, fxshlein, George Miroshnykov, ghostdunk, GusGold, Humberto Bruni, Ingo Eble, Isaac Parker, Jacob Ford, James Capuder, Jared Dziedzic, Jason DeStefano, Jason Dew, JavaXP, Jaxon Ketterman, jemmons, Jeremy, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel Miller, John Hamberger jn., John Meade, John Phelan, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, Larry, László Bácsi, Leo K, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mark Day, Martin Noble, Mats Fredriksson, Matthäus Pawelczyk, melvin2001, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Phil Dennis, Philip Hofstetter, Porus, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Robert Diaz, Robey Pointer, Sagnik Bhattacharya, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, solderspot, SonOfSofaman, Spencer Ruport, Splashtwist, Stefan Nesinger, Stefanus Du Toit, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Knowles, Tyler Latham, Vincent Bernat, Walter Montalvo, Warren Miller, Wim Coekaerts, Wraithan McCarroll, xisente, Yee Lam Wan


guid: yt:video:a6EWIh2D1NQ
title: Hacking a weird TV censoring device
author: Ben Eater
url: https://www.youtube.com/watch?v=a6EWIh2D1NQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/a6EWIh2D1NQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Here is the complete list of words I extracted: https://docs.google.com/spreadsheets/d/16D8GInFz3gchiAccVIclhMDHxzTxNQVli1lYfrW-m4s/edit#gid=0
And the original video from @TechnologyConnections: https://www.youtube.com/watch?v=ZiXg6H_FycI

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

Timestamps:
0:00 - What is the TV Guardian
0:50 - Circuit board analysis
3:15 - Removing and connecting to the ROM
6:10 - Extracting data from the ROM
14:22 - Analyzing the contents of the ROM

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, Alex Black, Andrew Van Gerpen, anula, Ben, Ben Cochran, Ben Kamens, Ben Williams, Bill Cooksey, Binh Tran, Богдан Федоров, Bradley Stach, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chaitanya Bhatt, Chris Lajoie, Chris Sachs, criis, Daniel Jeppsson, Daniel Pink, Daniel Tang, Dave Burley, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dušan Dželebdžić, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Thayer, Eveli László, Evin Dunn, Florian Rian, fxshlein, George Miroshnykov, ghostdunk, GusGold, Humberto Bruni, Ingo Eble, Isaac Parker, Jacob Ford, Jakob Dannesboe, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Dew, JavaXP, Jaxon Ketterman, jemmons, Jeremy, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel Miller, John Hamberger jn., John Henning, John Meade, John Phelan, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, Larry, László Bácsi, Leo K, Lithou, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mark Day, Martin Noble, Mats Fredriksson, Matthäus Pawelczyk, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Porus, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Robert Diaz, Robey Pointer, Sagnik Bhattacharya, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, solderspot, SonOfSofaman, Spencer Ruport, Splashtwist, Stefan Nesinger, Stefanus Du Toit, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Knowles, Tom Smith, Tyler Latham, Vincent Bernat, Walter Montalvo, Warren Miller, Wim Coekaerts, Wraithan McCarroll, xisente, Yee Lam Wan


guid: yt:video:4alV5LzHLE4
title: Let's build a voltage multiplier!
author: Ben Eater
url: https://www.youtube.com/watch?v=4alV5LzHLE4
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/4alV5LzHLE4?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
In this video, I explain the how a Dickson charge pump operates and how to build a basic example.

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, Alex Black, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Kamens, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Daniel Jeppsson, Daniel Pink, Daniel Tang, Darrell Burgoon, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dušan Dželebdžić, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, Florian Rian, fxshlein, George Miroshnykov, ghostdunk, GusGold, Humberto Bruni, Ingo Eble, Ivan Esparza, Jack McCracken, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Dew, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel Miller, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Leo K, Lithou, Lord Dorogoth, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mark Day, Martin Noble, MatrixSenpai, Mats Fredriksson, Matt Krueger, Matthäus Pawelczyk, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Splashtwist, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Knowles, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, xisente, Yee Lam Wan


guid: yt:video:oLYLnb7kpLg
title: 6502 serial interface
author: Ben Eater
url: https://www.youtube.com/watch?v=oLYLnb7kpLg
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/oLYLnb7kpLg?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, Alex Black, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, BRian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Jeppsson, Daniel Pink, Daniel Tang, Darrell Burgoon, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dušan Dželebdžić, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, GusGold, Hovis Biddle, Humberto Bruni, Ingo Eble, Ivan Esparza, Jack McCracken, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel Miller, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Leo K, Lithou, Lord Dorogoth, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, MatrixSenpai, Mats Fredriksson, Matt Krueger, Matthäus Pawelczyk, Matthew Clifford, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Knowles, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, xisente, Yee Lam Wan


guid: yt:video:zsERDRM1oy8
title: RS232 interface with the 6551 UART
author: Ben Eater
url: https://www.youtube.com/watch?v=zsERDRM1oy8
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/zsERDRM1oy8?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Jeppsson, Daniel Pink, Daniel Tang, Darrell Burgoon, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dušan Dželebdžić, Dustin Campbell, Dylan Speiser, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, GusGold, Hailey, Hovis Biddle, Humberto Bruni, Ingo Eble, Ivan Esparza, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel Miller, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lord Dorogoth, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matt Krueger, Matthew Clifford, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Rob Bruno, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Yee Lam Wan


guid: yt:video:CnA8nG3zYHw
title: Fixing a hardware bug in software (65C51 UART)
author: Ben Eater
url: https://www.youtube.com/watch?v=CnA8nG3zYHw
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/CnA8nG3zYHw?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Alex, Amit Bueno, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Jeppsson, Daniel Pink, Daniel Tang, Daniel Zimmer, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dušan Dželebdžić, Dustin Campbell, Dylan Speiser, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, GusGold, Hailey, Hovis Biddle, Ingo Eble, Ivan Esparza, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Jurģis Brigmanis, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lord Dorogoth, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Olivier HUBER, Ori Shamir, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Rob Bruno, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Walkowski, Tim Wheeler, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Yee Lam Wan


guid: yt:video:HlLCtjJzHVI
title: Running Apple 1 software on a breadboard computer (Wozmon)
author: Ben Eater
url: https://www.youtube.com/watch?v=HlLCtjJzHVI
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/HlLCtjJzHVI?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

0:00 Apple 1
2:06 Changes to make it work
3:13 What does Wozmon do?
6:35 Doing I/O
8:36 Running programs
10:44 Writing assembly programs
------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Amit Bueno, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Pink, Daniel Tang, Daniel Zimmer, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, GusGold, Hailey, Hovis Biddle, Ingo Eble, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael Koreshkov, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Mikel Lindsaar, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Olivier HUBER, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Rick Hennigan, Rob Bruno, Robert Diaz, Robert Evans, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tim Wheeler, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Yee Lam Wan


guid: yt:video:SpG8rgI7Hec
title: How Wozniak’s code for the Apple 1 works
author: Ben Eater
url: https://www.youtube.com/watch?v=SpG8rgI7Hec
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/SpG8rgI7Hec?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502 stuff: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

0:00 Variables
2:16 Hardware initialization
2:54 Reading input from the keyboard
10:18 Parsing the command
13:45 Parsing a hex value
21:29 Examine mode
28:28 Block examine mode
31:16 Store mode
34:28 Print routines

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chaitanya Bhatt, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Pink, Daniel Tang, Daniel Zimmer, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, Gregory Burns, GusGold, Hailey, Hovis Biddle, Ingo Eble, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael, Michael Cartwright, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Miles Macchiaroli, Muqeet Mujahid, NacOJerk, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Oli Homer, Olivier HUBER, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Richard Wagoner, Rick Hennigan, Rob Bruno, Robert Brown, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, sorek.uk, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tim Wheeler, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Yee Lam Wan


guid: yt:video:7M8LvMtdcgY
title: Adapting WozMon for the breadboard 6502
author: Ben Eater
url: https://www.youtube.com/watch?v=7M8LvMtdcgY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/7M8LvMtdcgY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, An Dương, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Bill Cooksey, Bill Watkins, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chaitanya Bhatt, Chris Anders, Chris Lajoie, Chris Sachs, criis, Cristi Cobzarenco, Daniel Pink, Daniel Tang, Daniel Zimmer, Dave Walter, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Bevan, Dean Winger, Deep Kalra, Dennis Henderson, Dennis Schubert, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, EvinSaysMarxWasRight!, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, Gregory Burns, GusGold, Hailey, Hovis Biddle, Ingo Eble, Jacob Ford, James Beldock, James Capuder, Jared Dziedzic, Jason Bowen, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Hamberger jn., John Henning, John Meade, Jon Dugan, Jonn Miller, Joseph Portaro, Josh Smith, Justin Graziani, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Lukasz Pacholik, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael, Michael Cartwright, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Paul Heller, Paul Pluzhnikov, Phil Dennis, Philip Hofstetter, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Richard Wagoner, Rick Hennigan, Rob Bruno, Robert Brown, Robert Diaz, Robert Keown, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Bright, Sean Patrick O’Brien, Sergey Kruk, Shane Mulcahy, SonOfSofaman, sorek.uk, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Tyler Latham, Usseod, Vincent Bernat, Warren Miller, Wim Coekaerts, Wraithan McCarroll, Yee Lam Wan


guid: yt:video:0q6Ujn_zNH8
title: A simple BIOS for my breadboard computer
author: Ben Eater
url: https://www.youtube.com/watch?v=0q6Ujn_zNH8
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/0q6Ujn_zNH8?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Anthony Weems, anula, Ben, Ben Cochran, Ben Williams, Benjamin Elder, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chai, Chris Anders, Chris Lajoie, criis, Cristi Cobzarenco, Daniel Tang, Daniel Zimmer, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, Florian Bürgi, fxshlein, George Miroshnykov, ghostdunk, Glen Jarvis, Gregory Burns, GusGold, Hailey, Hovis Biddle, Ingo Eble, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, Joey Murphy, John Henning, Jon Dugan, Jonn Miller, Josh Smith, Justin Williams, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, László Bácsi, Lithou, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael Cartwright, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, Mike Coate, mikebad, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Owen Arnett, Paul Heller, Paul Pluzhnikov, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, ReJ aka Renaldas Zioma, Ric King, Richard Wagoner, Rick Hennigan, Rob Bruno, Robert Brown, Robert Diaz, Robey Pointer, Roland Munsil, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, snc, SonOfSofaman, sorek.uk, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, TheWebMachine, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, tryonlinux, Tyler Latham, Vincent Bernat, Warren Miller, Wraithan McCarroll


guid: yt:video:XlbPnihCM0E
title: Running MSBASIC on my breadboard 6502 computer
author: Ben Eater
url: https://www.youtube.com/watch?v=XlbPnihCM0E
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/XlbPnihCM0E?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502: https://eater.net/6502
Code from this video: https://github.com/beneater/msbasic

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
19day, Adrien Friggeri, Aleksey Smolenchuk, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, criis, Cristi Cobzarenco, Daniel Tang, Daniel Zimmer, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, Florian Bürgi, fxshlein, George Harris, George Miroshnykov, ghostdunk, Glen Jarvis, Gregory Burns, GusGold, Hailey, Hovis Biddle, Ingo Eble, Ingram Leedy, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, James Will, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, John Henning, Jon Dugan, Jonn Miller, Josh Smith, Justin Graziani, Justin Williams, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kevin McQuown, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Lithou, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Mats Fredriksson, Matthew Clifford, melvin2001, Michael Cartwright, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, Mike Coate, mikebad, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Owen Arnett, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, Ric King, Richard Wagoner, Rick Hennigan, Rob Bruno, Robert Brown, Robert Diaz, Robey Pointer, Roland Munsil, Ryan Morrison, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, snc, SonOfSofaman, sorek.uk, Spencer Ruport, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Vincent Bernat, Warren Miller, Wraithan McCarroll

0:00 The MSBASIC code
1:42 Creating our own version of MSBASIC
4:53 Zero-page configuration
9:32 Configuring our version
13:08 Adding our BIOS code and Wozmon
14:15 Linker configuration
18:50 Pointing BASIC to our BIOS
23:09 Running BASIC!
26:32 Bugfixes and making control-C work
32:30 Everything is working
34:16 Not everything is working
35:29 Everything is actually working now


guid: yt:video:mpIFag8zSWo
title: How input buffering works
author: Ben Eater
url: https://www.youtube.com/watch?v=mpIFag8zSWo
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/mpIFag8zSWo?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Code from this video is at: https://github.com/beneater/msbasic
More 6502 stuff: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
19day, Adrien Friggeri, Aleksey Smolenchuk, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, criis, Cristi Cobzarenco, Daniel Tang, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Campbell, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Chancy, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, Florian Bürgi, George Harris, George Miroshnykov, ghostdunk, Glen Jarvis, Gregory Burns, GusGold, Hailey, Hovis Biddle, Ingo Eble, Ingram Leedy, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, James Chacon, James Will, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jeremy Cole, Jesse Miller, Jim Kelly, Jim Kelly, Jim Knowler, Joe Beda, Joe Pregracke, Joe Rork, Joel, John Henning, Jon Dugan, Jonn Miller, Josh Smith, Justin Graziani, Justin Williams, Kai Wells, Kefen, Ken Paul, Kennard Smith, Kenneth Christensen, Kevin McQuown, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Lithou, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Martin Noble, Matthew Clifford, melvin2001, Michael Cartwright, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Miles Macchiaroli, Muqeet Mujahid, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Owen Arnett, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, Ric King, Richard Wagoner, Rick Hennigan, Rob Bruno, Robert Brown, Robert Diaz, Robey Pointer, Roland Munsil, Ryan Morrison, Sagnik Bhattacharya, Sam Sturgis, Scott Gorlick, Scott Holmes, Sean Patrick O’Brien, Sergey Kruk, snc, SonOfSofaman, sorek.uk, Spencer Ruport, spookybassoon, Stefan Nesinger, Stephen Kovalcik, Stephen Riley, Steve  Jones, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Vaida N, Vitali Filinkou, Warren Miller, Wraithan McCarroll

0:00 - Unbuffered input
1:04 - Interrupts
3:20 - Circular buffer
5:01 - Setting up variables
7:25 - Buffer subroutines
10:45 - Interrupt handler
14:03 - New input routines
16:44 - Testing it out
17:50 - Fixing a bug
19:05 - Success!


guid: yt:video:LuKMVXWD7FY
title: RS232 flow control
author: Ben Eater
url: https://www.youtube.com/watch?v=LuKMVXWD7FY
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/LuKMVXWD7FY?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
More 6502: https://eater.net/6502
Hunt the Wumpus code: https://gist.github.com/beneater/742c988aad894ef9638331890a446b88

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adrien Friggeri, Aleksey Smolenchuk, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Borko Rajkovic, Bradley Stach, Brian Haug, Burt Humburg, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, Craig Hawco, criis, Cristi Cobzarenco, Daniel Tang, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Schoenbrun, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Chancy, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, Fifty1Ford, George Harris, George Miroshnykov, Glen Jarvis, Gregory Burns, GusGold, Hovis Biddle, Ingo Eble, Ingram Leedy, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, James Chacon, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jesse Miller, Jim Kelly, Jim Knowler, Jim Rees, Joe Beda, Joe Pregracke, Joe Rork, Joel, John Henning, John Rivoire, Jon Dugan, Jonn Miller, Josh Smith, Justin Williams, Kai Wells, Kefen, Kennard Smith, Kenneth Christensen, Kevin McQuown, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Léonard Hehlen, Lithou, Marcel Wysocki, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Mark Frankford, Martin Noble, Matthew Clifford, melvin2001, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Miles Macchiaroli, Mlok Karel, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Owen Arnett, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, Richard Wagoner, Rick Hennigan, Robert Diaz, Robert Walsh, Robey Pointer, Roland Munsil, Ryan Morrison, Sagnik Bhattacharya, Sam Sturgis, Scott Holmes, Sean Patrick O’Brien, Sebastian Kopeć, SergeantBiggs, Sergey Kruk, snc, SonOfSofaman, sorek.uk, spookybassoon, Stefan Nesinger, Stéphane Dumont, Stephen Kovalcik, Stephen Riley, Steve  Jones, Steve Harris, This person's name is too hard to pronounce, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Vaida Narušė, Warren Miller, Wraithan McCarroll


guid: yt:video:gOwi2p1pzVM
title: Hacking Microsoft BASIC
author: Ben Eater
url: https://www.youtube.com/watch?v=gOwi2p1pzVM
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/gOwi2p1pzVM?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Code: https://github.com/beneater/msbasic
More 6502: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

0:00 - Peek and poke
2:13 - Poking to the LCD
5:33 - Adding new BASIC instructions
8:45 - LCDPRINT instruction
12:15 - LCDCMD instruction
12:41 - Initializing the LCD
15:16 - Testing it out

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adam Bursey, Adrien Friggeri, Aleksey Smolenchuk, aliceitc, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Богдан Федоров, Borko Rajkovic, Bradley Stach, Brian Haug, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, Craig Hawco, criis, Cristi Cobzarenco, Daniel Tang, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Klassen, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Schoenbrun, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Chancy, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, Fifty1Ford, George Harris, George Miroshnykov, Glen Jarvis, Gregory Burns, GusGold, Hovis Biddle, Ingo Eble, Ingram Leedy, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, James Chacon, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jesse Miller, Jim Kelly, Jim Knowler, Jim Rees, Joe Beda, Joel, John Henning, John Rivoire, Jon Dugan, Jonn Miller, Josh Smith, Justin Williams, Kai Wells, Kefen, Kennard Smith, Kenneth Christensen, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Léonard Hehlen, Lithou, Marcel Wysocki, Marcos Fujisawa, Marcus Classon, Mariano Uvalle, Mark Day, Mark Frankford, Martin Noble, Matthew Clifford, melvin2001, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, Miguel Ríos, mikebad, Miles Macchiaroli, Mlok Karel, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, Olivier HUBER, Örn Arnarson, Owen Arnett, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Ralph Irons, Randal Masutani, Randy True, raoulvp, real_huitz, Richard Wagoner, Rick Hennigan, Robert Diaz, Robert Walsh, Robey Pointer, Roland Munsil, Ryan Morrison, Sagnik Bhattacharya, Sam Sturgis, Scott Holmes, Sean Patrick O’Brien, Sebastian Kopeć, SergeantBiggs, Sergey Kruk, snc, SonOfSofaman, sorek.uk, spookybassoon, Stefan Nesinger, Stéphane Dumont, Stephen Kovalcik, Stephen Riley, Steve  Jones, Steve Harris, Temo Tchanukvadze, This person's name is too hard to pronounce, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Vaida Narušė, Warren Miller, Wraithan McCarroll


guid: yt:video:aVVKgwr_SfQ
title: Reverse engineering Microsoft BASIC
author: Ben Eater
url: https://www.youtube.com/watch?v=aVVKgwr_SfQ
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCS0N5baNlQWJCUrhCEo8WlA
enclosure_url: https://www.youtube.com/v/aVVKgwr_SfQ?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
Code: https://github.com/beneater/msbasic
More 6502: https://eater.net/6502

Support these videos on Patreon: https://www.patreon.com/beneater or https://eater.net/support for other ways to support.

0:00 - Previous functionality
1:28 - Analyzing PRINT code
6:24 - Looking at what's in the zero page
16:38 - Copying logic from PRINT
19:30 - String descriptors and memory management
25:23 - Testing it out

------------------

Social media:
Website: https://www.eater.net
Twitter: https://twitter.com/ben_eater
Patreon: https://patreon.com/beneater
Reddit: https://www.reddit.com/r/beneater

Special thanks to these supporters for making this video possible:
Adam Bursey, Adrien Friggeri, Aleksey Smolenchuk, aliceitc, Anthony Weems, anula, Ben, Ben Cochran, Benjamin D. Williams, Benjamin Elder, Benjamin Keil, Benji Bromberg, Bill Cooksey, Binh Tran, Borko Rajkovic, Bradley Stach, Brian Haug, Carl Fooks, Carsten Schwender, Chad Fertig, Chai, Chris Anders, Chris Lajoie, Craig Hawco, criis, Cristi Cobzarenco, Daniel Tang, Dave Walter, Dave Westwood, David Clark, David Cox, David Dawkins, David House, David Sastre Medina, David Turner, Dean Winger, Deep Kalra, DemoniacDeath, Dennis Henderson, Derek Chandler, Dilip Gowda, Dirk Sperling, Dmitry Guyvoronsky, Dustin Schoenbrun, Dzevad Trumic, Emilio Mendoza, Eric Dynowski, Erik Broeders, Erik Chancy, Erik Granlund, Ethan Sifferman, Eugene Bulkin, Evan Serrano, Evan Thayer, Eveli László, George Harris, George Miroshnykov, Glen Jarvis, Glenn Davidson, Gregory Burns, GusGold, Hovis Biddle, Ingo Eble, Ingram Leedy, Isaac Parker, Jack McKinney, Jacob Ford, James Capuder, James Chacon, Jason DeStefano, Jason Grim, Jason Thorpe, JavaXP, Jaxon Ketterman, jemmons, Jesse Miller, Jim Kelly, Jim Knowler, Jim Rees, Joe Beda, Joel, John Haugabook, John Rivoire, Jon Dugan, Jonn Miller, Josh Smith, Justin Williams, Kai Wells, Kefen, Kennard Smith, Kenneth Christensen, Kristian Høy Horsberg, Kyle Kellogg, Lambda GPU Workstations, Larry Scherr, László Bácsi, Lithou, Marcel Wysocki, Marcos Fujisawa, Mariano Uvalle, Mark Day, Mark Frankford, Martin Noble, Matt Krueger, melvin2001, MICHAEL SLASS, Michael Tedder, Michael Timbrook, Michael Weitman, mikebad, Miles Macchiaroli, Mlok Karel, Nate Welch, Nicholas Counts, Nicholas Moresco, Nick Chapman, NormalLuser, Olivier HUBER, Örn Arnarson, Owen Arnett, Pat Nakajima, Paul Heller, Paul Pluzhnikov, Pete Dietl, Phil Dennis, Philip Hofstetter, Ponytail Bob, ProgrammerDor, Randal Masutani, Randy True, raoulvp, real_huitz, Richard Wagoner, Robert Diaz, Robert Walsh, Robey Pointer, Roland Munsil, Ryan, Ryan Morrison, Sagnik Bhattacharya, Sam Sturgis, Scott Holmes, Sean Patrick O’Brien, Sebastian Kopeć, SergeantBiggs, Sergey Kruk, snc, SonOfSofaman, sorek.uk, spookybassoon, Stefan Nesinger, Stéphane Dumont, Stephen Kovalcik, Stephen Riley, Steve  Jones, Steve Harris, This person's name is too hard to pronounce, Thomas Eriksen, Tim Oriol, Tim Sanders, Tim Walkowski, Tom, Tom Smith, Trevor Johnston, Trey Webb, tryonlinux, Tyler Latham, Vaida Narušė, Victor Kazakov, Warren Miller, Wraithan McCarroll


guid: yt:video:pNp4ug5F6To
title: Polishing and Releasing My Tiny Geography Game
author: Sebastian Lague
url: https://www.youtube.com/watch?v=pNp4ug5F6To
feedurl: https://www.youtube.com/feeds/videos.xml?channel_id=UCmtyQOKKmrMVaKuRXz02jbQ
enclosure_url: https://www.youtube.com/v/pNp4ug5F6To?version=3
enclosure_type: application/x-shockwave-flash
content_mime_type: text/plain
content:
I've been making some small tweaks and additions to my little geography game based on the great feedback I've received from all of you (thank you!).

If you'd like to play the game, you can download it here: https://sebastian.itch.io/geographical-adventures

The project source is over here: https://github.com/SebLague/Geographical-Adventures

If you'd like to support my work (and get early access to new videos and projects), please consider becoming a patron of the channel over here:
https://www.patreon.com/SebastianLague

Project playlist: https://youtube.com/playlist?list=PLFt_AvWsXl0dT82XMtKATYPcVIhpu2fh6

Chapters
0:00 Intro
0:17 Creating a Compass
3:58 Making a Map
10:47 Tweaking the Terrain
13:13 Better city lights
15:40 Star Colour
16:27 Nighttime Visibility
17:26 Hot Air Balloons
19:52 Speed Control
21:34 Skywriting Experiment
24:18 The Final Result

Music:
Spread your Wings - Evgeny Bardyuzha
Immersion - Michael FK
Back Home - Max H
Icicles - Biba Dupont
Less Traveled - Hans Johnson
Let the Rains Come - We Dream of Eden
How it Was - Laurel Violet
Brightest - Ardie Son
L'Absinthe Brûle - Biba Dupont
It Will Come Back - The Stolen Orchestra
Over the Canyon - Gray North
Autumn in Paris - Jan Baars
Passion - Veaceslav Draganov


