<?xml version="1.0" ?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns1="http://www.w3.org/2005/Atom" xmlns:ns2="http://purl.org/rss/1.0/modules/content/" version="2.0">
	<channel>
		<title>Omar Shehata's writing</title>
		<link>http://omarshehata.me</link>
		<image>
			<url>https://omarshehata.me/static/whoisomar/tesseract.png</url>
			<title>Omar Shehata's writing</title>
			<link>http://omarshehata.me</link>
		</image>
		<description>I write to help myself understand how the world works. Usually about computer graphics / math. I also write personal reflections on life &amp; culture, and whatever I happen to be interested in that week.</description>
		<language>en-us</language>
		<lastBuildDate>Mon, 06 Apr 2026 12:00:01 </lastBuildDate>



		<item>
			<title>Creating a DOOM-inspired aesthetic with PlayCanvas</title>
			<link>https://omarshehata.me/html/playcanvas-horror-aesthetic/</link>
			<guid>https://omarshehata.me/html/playcanvas-horror-aesthetic/</guid>
			<description>
				&lt;p&gt;Last week I made a game called Death's Clutch in 10 days for a game jam hosted by Newgrounds. Making it was a lot of fun because it involved a lot of customized rendering like making DOOM-inspired 2D billboards that move in 3D, or hacking PlayCanvas's material system to get stylized lighting.&lt;/p&gt;

				&lt;p&gt;I hope this "how it's made" article will be useful for others seeking to stylize their PlayCanvas games, and I'm curious if any readers know of better ways to implement these effects (especially curious about comparing with other engines/workflows).&lt;/p&gt;

				&lt;img src="https://omarshehata.me/static/whoisomar/images/notebook/deaths_clutch.jpeg"&gt;
			</description>
			<pubDate>Sat, 31 Jul 2021 00:00:00 </pubDate>		
		</item>

		<item>
			<title>Why does the same note sound different across instruments?</title>
			<link>https://omarshehata.me/notebook/exploring_sound</link>
			<guid>https://omarshehata.me/notebook/exploring_sound</guid>
			<category>explorable</category>
			<description>
				I really wanted to answer this question for myself from first principles. This ended up being a fun exploration of timbre and Fourier transforms.

				&lt;img src="https://omarshehata.me/static/whoisomar/images/notebook/sound.png"&gt; 
			</description>
			<pubDate>Sun, 28 Feb 2021 00:00:00 </pubDate>					
		</item>

		<item>
			<title>Unraveling the JPEG</title>
			<link>https://parametric.press/issue-01/unraveling-the-jpeg/</link>
			<guid>https://parametric.press/issue-01/unraveling-the-jpeg/</guid>
			<category>explorable</category>
			<description>
				Learn about image compression by looking at the raw image bytes and how they get encoded/decoded.
				&lt;img src="https://omarshehata.me/static/whoisomar/images/jpeg-article.jpeg"&gt; 
			</description>

			<pubDate>Wed, 01 May 2019 00:13:00 GMT</pubDate>					
		</item>

		<item>
			<title>Linear Discriminant Analysis</title>
			<link>https://omarshehata.github.io/lda-explorable/</link>
			<guid>https://omarshehata.github.io/lda-explorable/</guid>
			<category>explorable</category>
			<description>
				LDA is a technique for working with higher dimensional data that was always presented analytically to me, and I wanted to see it visually.

				&lt;img src="https://omarshehata.me/static/whoisomar/images/lda.gif"&gt; 
			</description>
			<pubDate>Mon, 03 Dec 2018 00:13:00 GMT</pubDate>					
		</item>

		<item>
				<title>The Mystery of the Corrupted MIDI File (Untangling an encoding mess with JavaScript Typed Arrays)</title>
				<link>https://blog.logrocket.com/binary-data-in-the-browser-untangling-an-encoding-mess-with-javascript-typed-arrays-119673c0f1fe/</link>
				<guid>https://blog.logrocket.com/binary-data-in-the-browser-untangling-an-encoding-mess-with-javascript-typed-arrays-119673c0f1fe/</guid>
				<description>
					Learning how to debug a corrupted MIDI file takes us down a journey into binary data, encoding, and typed arrays.

					&lt;img src="https://storage.googleapis.com/blog-images-backup/1*MPpfSHYOlpIBcdaPQXBBRQ.png"&gt; 
				</description>
				<pubDate>Tue May 22 2018 00:13:00 GMT</pubDate>					
			</item>


			<item>
				<title>A Beginner's Guide to Coding Graphics Shaders</title>
				<link>https://gamedevelopment.tutsplus.com/a-beginners-guide-to-coding-graphics-shaders--cms-23313t</link>
				<guid>https://gamedevelopment.tutsplus.com/a-beginners-guide-to-coding-graphics-shaders--cms-23313t</guid>
				<description>
					Shader programming can come off as enigmatic black magic, and is often misunderstood. There are many code samples out there that demonstrate incredible...
					
					&lt;img src="https://cms-assets.tutsplus.com/cdn-cgi/image/width=300/uploads/users/728/posts/23313/preview_image/thumb2.jpg"&gt; 
				</description>
				<pubDate>Wed Apr 15 2015 00:13:00 GMT</pubDate>					
			</item>

		

	<item>
	<title>Dall e telephone</title>
	<link>https://omarshehata.me/notebook/dall_e_telephone</link>
	<guid>https://omarshehata.me/notebook/dall_e_telephone</guid>
	<pubDate>Fri, 06 Sep 2024 00:00:00 </pubDate>					
</item><item>
	<title>Office snapshot</title>
	<link>https://omarshehata.me/notebook/office_snapshot</link>
	<guid>https://omarshehata.me/notebook/office_snapshot</guid>
	<pubDate>Mon, 10 Jun 2024 00:00:00 </pubDate>					
</item><item>
	<title>Rosanos gift</title>
	<link>https://omarshehata.me/notebook/rosanos_gift</link>
	<guid>https://omarshehata.me/notebook/rosanos_gift</guid>
	<pubDate>Thu, 16 May 2024 00:00:00 </pubDate>					
</item><item>
	<title>My new radio</title>
	<link>https://omarshehata.me/notebook/my_new_radio</link>
	<guid>https://omarshehata.me/notebook/my_new_radio</guid>
	<pubDate>Wed, 21 Feb 2024 00:00:00 </pubDate>					
</item><item>
	<title>Scenes from egypt</title>
	<link>https://omarshehata.me/notebook/scenes_from_egypt</link>
	<guid>https://omarshehata.me/notebook/scenes_from_egypt</guid>
	<pubDate>Wed, 01 Nov 2023 00:00:00 </pubDate>					
</item><item>
	<title>Outdoor cats &amp; epistemology</title>
	<link>https://omarshehata.me/notebook/outdoor_cats_&amp;_epistemology</link>
	<guid>https://omarshehata.me/notebook/outdoor_cats_&amp;_epistemology</guid>
	<pubDate>Fri, 15 Sep 2023 00:00:00 </pubDate>					
</item><item>
	<title>Glimpse into recent news in egypt</title>
	<link>https://omarshehata.me/notebook/glimpse_into_recent_news_in_egypt</link>
	<guid>https://omarshehata.me/notebook/glimpse_into_recent_news_in_egypt</guid>
	<pubDate>Mon, 07 Aug 2023 00:00:00 </pubDate>					
</item><item>
	<title>Debugging double tap in godot</title>
	<link>https://omarshehata.me/notebook/debugging_double_tap_in_godot</link>
	<guid>https://omarshehata.me/notebook/debugging_double_tap_in_godot</guid>
	<pubDate>Sun, 07 May 2023 00:00:00 </pubDate>					
</item><item>
	<title>Mapping my ithaca</title>
	<link>https://omarshehata.me/notebook/mapping_my_ithaca</link>
	<guid>https://omarshehata.me/notebook/mapping_my_ithaca</guid>
	<pubDate>Sat, 03 Dec 2022 00:00:00 </pubDate>					
</item><item>
	<title>My newsletter</title>
	<link>https://omarshehata.me/notebook/my_newsletter</link>
	<guid>https://omarshehata.me/notebook/my_newsletter</guid>
	<pubDate>Thu, 10 Nov 2022 00:00:00 </pubDate>					
</item><item>
	<title>Biking in alaska</title>
	<link>https://omarshehata.me/notebook/biking_in_alaska</link>
	<guid>https://omarshehata.me/notebook/biking_in_alaska</guid>
	<pubDate>Sun, 31 Jul 2022 00:00:00 </pubDate>					
</item><item>
	<title>Tell yourself better stories</title>
	<link>https://omarshehata.me/notebook/tell_yourself_better_stories</link>
	<guid>https://omarshehata.me/notebook/tell_yourself_better_stories</guid>
	<pubDate>Mon, 25 Jul 2022 00:00:00 </pubDate>					
</item><item>
	<title>My number forms</title>
	<link>https://omarshehata.me/notebook/my_number_forms</link>
	<guid>https://omarshehata.me/notebook/my_number_forms</guid>
	<pubDate>Sat, 23 Jul 2022 00:00:00 </pubDate>					
</item><item>
	<title>Improv math song</title>
	<link>https://omarshehata.me/notebook/improv_math_song</link>
	<guid>https://omarshehata.me/notebook/improv_math_song</guid>
	<pubDate>Sat, 09 Jul 2022 00:00:00 </pubDate>					
</item><item>
	<title>My favorite memory palace episodes</title>
	<link>https://omarshehata.me/notebook/my_favorite_memory_palace_episodes</link>
	<guid>https://omarshehata.me/notebook/my_favorite_memory_palace_episodes</guid>
	<pubDate>Wed, 08 Jun 2022 00:00:00 </pubDate>					
</item><item>
	<title>Seattle sunset</title>
	<link>https://omarshehata.me/notebook/seattle_sunset</link>
	<guid>https://omarshehata.me/notebook/seattle_sunset</guid>
	<pubDate>Fri, 15 Apr 2022 00:00:00 </pubDate>					
</item><item>
	<title>Notes on infinite powers</title>
	<link>https://omarshehata.me/notebook/notes_on_infinite_powers</link>
	<guid>https://omarshehata.me/notebook/notes_on_infinite_powers</guid>
	<pubDate>Mon, 04 Apr 2022 00:00:00 </pubDate>					
</item><item>
	<title>Project ideas</title>
	<link>https://omarshehata.me/notebook/project_ideas</link>
	<guid>https://omarshehata.me/notebook/project_ideas</guid>
	<pubDate>Tue, 01 Feb 2022 00:00:00 </pubDate>					
</item><item>
	<title>Notes on 10 percent happier</title>
	<link>https://omarshehata.me/notebook/notes_on_10_percent_happier</link>
	<guid>https://omarshehata.me/notebook/notes_on_10_percent_happier</guid>
	<pubDate>Tue, 28 Dec 2021 00:00:00 </pubDate>					
</item><item>
	<title>Let it be genre defining</title>
	<link>https://omarshehata.me/notebook/let_it_be_genre_defining</link>
	<guid>https://omarshehata.me/notebook/let_it_be_genre_defining</guid>
	<pubDate>Mon, 04 Oct 2021 00:00:00 </pubDate>					
</item><item>
	<title>A still more glorious dawn awaits</title>
	<link>https://omarshehata.me/notebook/a_still_more_glorious_dawn_awaits</link>
	<guid>https://omarshehata.me/notebook/a_still_more_glorious_dawn_awaits</guid>
	<pubDate>Thu, 16 Sep 2021 00:00:00 </pubDate>					
</item><item>
	<title>Recreating light art</title>
	<link>https://omarshehata.me/notebook/recreating_light_art</link>
	<guid>https://omarshehata.me/notebook/recreating_light_art</guid>
	<pubDate>Mon, 13 Sep 2021 00:00:00 </pubDate>					
</item><item>
	<title>Do it even if you dont feel like it</title>
	<link>https://omarshehata.me/notebook/do_it_even_if_you_dont_feel_like_it</link>
	<guid>https://omarshehata.me/notebook/do_it_even_if_you_dont_feel_like_it</guid>
	<pubDate>Mon, 13 Sep 2021 00:00:00 </pubDate>					
</item><item>
	<title>Cync - exploring non quantized music</title>
	<link>https://omarshehata.me/notebook/cync_-_exploring_non_quantized_music</link>
	<guid>https://omarshehata.me/notebook/cync_-_exploring_non_quantized_music</guid>
	<pubDate>Sat, 07 Aug 2021 00:00:00 </pubDate>					
</item><item>
	<title>Behind the scenes of deaths clutch</title>
	<link>https://omarshehata.me/notebook/behind_the_scenes_of_deaths_clutch</link>
	<guid>https://omarshehata.me/notebook/behind_the_scenes_of_deaths_clutch</guid>
	<pubDate>Sat, 31 Jul 2021 00:00:00 </pubDate>					
</item><item>
	<title>Do what is hard</title>
	<link>https://omarshehata.me/notebook/do_what_is_hard</link>
	<guid>https://omarshehata.me/notebook/do_what_is_hard</guid>
	<pubDate>Thu, 08 Jul 2021 00:00:00 </pubDate>					
</item><item>
	<title>The hidden gallery</title>
	<link>https://omarshehata.me/notebook/the_hidden_gallery</link>
	<guid>https://omarshehata.me/notebook/the_hidden_gallery</guid>
	<pubDate>Sat, 05 Jun 2021 00:00:00 </pubDate>					
</item><item>
	<title>How to turn an image black and white</title>
	<link>https://omarshehata.me/notebook/how_to_turn_an_image_black_and_white</link>
	<guid>https://omarshehata.me/notebook/how_to_turn_an_image_black_and_white</guid>
	<pubDate>Mon, 12 Apr 2021 00:00:00 </pubDate>					
</item><item>
	<title>The best zoom call</title>
	<link>https://omarshehata.me/notebook/the_best_zoom_call</link>
	<guid>https://omarshehata.me/notebook/the_best_zoom_call</guid>
	<pubDate>Sun, 04 Apr 2021 00:00:00 </pubDate>					
</item><item>
	<title>Playing celeste is like learning the piano</title>
	<link>https://omarshehata.me/notebook/playing_celeste_is_like_learning_the_piano</link>
	<guid>https://omarshehata.me/notebook/playing_celeste_is_like_learning_the_piano</guid>
	<pubDate>Mon, 22 Mar 2021 00:00:00 </pubDate>					
</item><item>
	<title>Why I dislike movie previews</title>
	<link>https://omarshehata.me/notebook/why_i_dislike_movie_previews</link>
	<guid>https://omarshehata.me/notebook/why_i_dislike_movie_previews</guid>
	<pubDate>Sun, 21 Mar 2021 00:00:00 </pubDate>					
</item><item>
	<title>Studying the night of the exam</title>
	<link>https://omarshehata.me/notebook/studying_the_night_of_the_exam</link>
	<guid>https://omarshehata.me/notebook/studying_the_night_of_the_exam</guid>
	<pubDate>Tue, 02 Feb 2021 00:00:00 </pubDate>					
</item><item>
	<title>An ode to snow</title>
	<link>https://omarshehata.me/notebook/an_ode_to_snow</link>
	<guid>https://omarshehata.me/notebook/an_ode_to_snow</guid>
	<pubDate>Sun, 20 Dec 2020 00:00:00 </pubDate>					
</item><item>
	<title>Visualizing the solar analemma</title>
	<link>https://omarshehata.me/notebook/visualizing_the_solar_analemma</link>
	<guid>https://omarshehata.me/notebook/visualizing_the_solar_analemma</guid>
	<pubDate>Mon, 07 Dec 2020 00:00:00 </pubDate>					
</item><item>
	<title>On inspiration and determination</title>
	<link>https://omarshehata.me/notebook/on_inspiration_and_determination</link>
	<guid>https://omarshehata.me/notebook/on_inspiration_and_determination</guid>
	<pubDate>Tue, 01 Dec 2020 00:00:00 </pubDate>					
</item><item>
	<title>A preface to learning english</title>
	<link>https://omarshehata.me/notebook/a_preface_to_learning_english</link>
	<guid>https://omarshehata.me/notebook/a_preface_to_learning_english</guid>
	<pubDate>Wed, 25 Nov 2020 00:00:00 </pubDate>					
</item><item>
            <title>WebGL / WebGPU Jan 2023 meetup highlights</title>
            <link>https://omar-shehata.medium.com/webgl-webgpu-jan-2023-meetup-highlights-d29f9e0d0bdc?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/d29f9e0d0bdc</guid>
            <category>webgpu</category>
            <category>web</category>
            <category>computer-graphics</category>
            <category>javascript</category>
            <category>webgl</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Wed, 01 Feb 2023 17:18:26 GMT</pubDate>
            <ns1:updated>2023-02-03T01:17:07.168Z</ns1:updated>
            <description>&lt;p&gt;The &lt;a href="https://www.khronos.org/events/webgl-webgpu-meetup-january-2023"&gt;Khronos WebGL/WebGPU meetup&lt;/a&gt; is a recurring online event where the folks working on these web graphics API’s share updates followed by talks from the community.&lt;/p&gt;&lt;p&gt;Here I’ve summarized my personal highlights &amp;amp; takeaways from this week’s meetup.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Recording link: &lt;/strong&gt;&lt;a href="https://www.youtube.com/watch?v=Jl06sOvMnvU"&gt;https://www.youtube.com/watch?v=Jl06sOvMnvU&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;For my past event recaps, see &lt;/em&gt;&lt;a href="https://medium.com/@omar-shehata/webgl-webgpu-april-2022-meetup-highlights-e57ad07e1f60"&gt;&lt;em&gt;April 2022&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, &lt;/em&gt;&lt;a href="https://omar-shehata.medium.com/webgpu-january-2022-meetup-takeaways-4cbe03d088b1"&gt;&lt;em&gt;January 2022&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, &lt;/em&gt;&lt;a href="https://omar-shehata.medium.com/my-takeaways-from-webgpu-july-2021-meetup-8c27244e8b8f?source=your_stories_page-------------------------------------"&gt;&lt;em&gt;July 2021&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;WebGL Updates&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Ken Russell, Khronos Group&lt;br&gt;&lt;/em&gt;&lt;a href="https://khr.io/web202301"&gt;&lt;em&gt;Slides&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Some of the things Ken was most excited to share:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Wide color gamut support coming to WebGL&lt;/strong&gt; — allows you to make use of newer displays with more vibrant color spaces&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Proposed &lt;/strong&gt;&lt;a href="https://registry.khronos.org/webgl/extensions/proposals/ANGLE_shader_pixel_local_storage/"&gt;&lt;strong&gt;Pixel Local Storag&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;e extension &lt;/strong&gt;— it potentially has “dramatic performance improvements for many use cases”. Can follow its development &lt;a href="https://bugs.chromium.org/p/angleproject/issues/detail?id=7279"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/"&gt;&lt;strong&gt;Provoking vertex extension&lt;/strong&gt;&lt;/a&gt; — can improve performance a lot for applications using flat shading.&lt;/li&gt;&lt;li&gt;&lt;a href="https://registry.khronos.org/webgl/extensions/proposals/EXT_polygon_offset_clamp/"&gt;&lt;strong&gt;Proposed polygon offset clamp extension&lt;/strong&gt;&lt;/a&gt; — easy to use extension that reduces many artifacts in real time shadows&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Ken also shared that they are very close to shipping WebGL’s ANGLE/Metal backend. This is exciting because it’ll allow WebGL applications to continue being fully supported on the latest Metal API across MacOS &amp;amp; iOS.&lt;/p&gt;&lt;p&gt;&lt;a href="https://arm-software.github.io/opengl-es-sdk-for-android/translucency.html"&gt;I found this to be a good article&lt;/a&gt; on what pixel local storage is. It allows you to write per-pixel data to a fast on-chip storage, removing the need to write to a buffer for many lighting techniques. So that uses less memory and is also much faster.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.khronos.org/opengl/wiki/Primitive#Provoking_vertex"&gt;The OpenGL wiki&lt;/a&gt; has a good explanation for what the “provoking vertex” is, see also &lt;a href="https://github.com/KhronosGroup/WebGL/issues/3401"&gt;a discussion on it in WebGL&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;WebGPU Updates&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Kelsey Gilbert, Mozilla&lt;br&gt;Slides (same as above)&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;v1.0 is almost there! Currently targeting 2023 Q1. &lt;strong&gt;Expecting release around Chromium version 113 &lt;/strong&gt;(see &lt;a href="https://chromiumdash.appspot.com/schedule"&gt;release schedule&lt;/a&gt;) on Windows, ChromeOS, and MacOS (and Linux and Android later)&lt;/li&gt;&lt;li&gt;Lots of progress on &lt;strong&gt;using WebGPU outside the browser&lt;/strong&gt;: (1) &lt;a href="https://deno.land/"&gt;Deno&lt;/a&gt; has built in &lt;a href="https://deno.land/x/deno@v1.9.2/op_crates/webgpu"&gt;WebGPU support&lt;/a&gt; (2) &lt;a href="https://dawn.googlesource.com/dawn"&gt;Dawn&lt;/a&gt;, a cross platform implementation of WebGPU, is “99% on par with Chromium” and has Node bindings&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Kelsey called for community support for helping develop WebGPU. The best ways to contribute right now are (1) providing feedback on the API &amp;amp; general usage through &lt;a href="https://github.com/gpuweb/gpuweb/discussions"&gt;GitHub&lt;/a&gt; or &lt;a href="https://matrix.to/#/#WebGPU:matrix.org"&gt;Matrix chat&lt;/a&gt;, she emphasized this is now the time when feedback would be most impactful &amp;amp; helpful (2) help &lt;a href="https://github.com/gpuweb/cts/blob/main/docs/intro/README.md"&gt;writing conformance tests&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;ThreeJS &amp;amp; WebGPU&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;Ricardo Cabello, Google&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://twitter.com/mrdoob"&gt;Mrdoob&lt;/a&gt; talked about how ThreeJS has been working towards supporting WebGPU. &lt;strong&gt;The biggest obstacle to making it a drop-in replacement for WebGL is that WebGL shaders must be written in GLSL and WebGPU shaders are WGSL.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The reason this is a problem for ThreeJS is that many developers use &lt;a href="https://threejs.org/docs/#api/en/materials/Material.onBeforeCompile"&gt;material.onBeforeCompile&lt;/a&gt; to edit the generated shader GLSL code before it is compiled, to create custom materials. WebGPU would be a breaking change for this because you’d need to rewrite your modifications in WGSL.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;“&lt;/strong&gt;&lt;a href="https://www.donmccurdy.com/2019/03/17/three-nodematerial-introduction/"&gt;&lt;strong&gt;NodeMaterial&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; to the rescue!”&lt;/strong&gt; says Mrdoob. Instead of writing your materials in GLSL or WGSL, or any shading language, you write it in this higher level node system, and it’ll be easy for the engine to generate the right shader for the renderer/platform.&lt;/p&gt;&lt;p&gt;Below is an example code snippet (&lt;a href="https://github.com/mrdoob/three.js/blob/df181a2086474b5ba60cdf20b8b3cfb0592452ff/examples/webgl_nodes_loader_gltf_iridescence.html#L89-L97"&gt;source&lt;/a&gt;) for this &lt;a href="https://threejs.org/examples/?q=gltf#webgl_loader_gltf_iridescence"&gt;iridescence material demo&lt;/a&gt;.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/882/1*omE5cooMMxTv5_1pafXfdg.png" /&gt;&lt;figcaption&gt;&lt;a href="https://github.com/mrdoob/three.js/blob/df181a2086474b5ba60cdf20b8b3cfb0592452ff/examples/webgl_nodes_loader_gltf_iridescence.html#L89-L97"&gt;Source code link&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/873/1*vhVSsNOe6YPavTgIr5_hGw.png" /&gt;&lt;figcaption&gt;&lt;a href="https://threejs.org/examples/?q=gltf#webgl_loader_gltf_iridescence"&gt;https://threejs.org/examples/?q=gltf#webgl_loader_gltf_iridescence&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;They’ve also built a nodes material editor playground you can use to interactively create and edit these kinds of materials:&lt;/p&gt;&lt;p&gt;&lt;a href="https://threejs.org/examples/?q=nodes#webgl_nodes_playground"&gt;https://threejs.org/examples/?q=nodes#webgl_nodes_playground&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/880/1*7I6FzU0SYY1ibqnNCAMLVw.png" /&gt;&lt;figcaption&gt;&lt;a href="https://threejs.org/examples/?q=nodes#webgl_nodes_playground"&gt;https://threejs.org/examples/?q=nodes#webgl_nodes_playground&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Mrdoob mentioned that they’ve been looking at MaterialX (&lt;a href="https://materialx.org/"&gt;https://materialx.org/&lt;/a&gt;) as an open standard for representing these kinds of materials. They’ve been trying to generally align how they design the materials in ThreeJS with this standard so they aren’t reinventing everything from scratch.&lt;/p&gt;&lt;p&gt;MaterialX already has a lot of support in various engines &amp;amp; authoring tools, and &lt;a href="https://threejs.org/examples/?q=materialx#webgl_nodes_loader_materialx"&gt;ThreeJS now has a loader for it&lt;/a&gt;. This is exciting because it means you can export your models from Blender &amp;amp; Maya etc and get them to look exactly the same on the web with ThreeJS.&lt;/p&gt;&lt;p&gt;A final resource Mrdoob shared was &lt;a href="https://nodetoy.co/"&gt;NodeToy&lt;/a&gt;, an interactive playground where you can create, edit, and share materials with a node editor. It even generates ThreeJS code or GLSL code for any of the materials on the site.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/979/1*bze6_20_1x-VtB_G9Kk6eg.png" /&gt;&lt;figcaption&gt;&lt;a href="https://nodetoy.co/"&gt;https://nodetoy.co/&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Mrdoob mentioned there’ll still be an option to write your own shaders if you want to, but for most use cases NodeMaterial will be the way to go.&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;A technical journey through Google Earth&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;&lt;em&gt;John Anderson, Google&lt;/em&gt;&lt;/p&gt;&lt;p&gt;John talked about the evolution of Google Earth’s technical architecture over the years, starting with this awesome sneak peak of the very first time they tried running it with Emscripten and AsmJS:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kBcObKg360-Y5bKQzS1Vfw.png" /&gt;&lt;/figure&gt;&lt;p&gt;Originally Google Earth only worked in Chrome, running native code with &lt;a href="https://developer.chrome.com/docs/native-client/nacl-and-pnacl/"&gt;PNaCL&lt;/a&gt;. This is the reason they always had a “launch” button earth.google.com instead of being able to launch directly to the app.&lt;/p&gt;&lt;p&gt;The switch to a fully WebAssembly version happened in 2020, and allowed it to work in all browsers. In 2021 the “launch” button was removed. Google Earth now runs on a shared C++ renderer across Web, Android, and iOS.&lt;/p&gt;&lt;p&gt;There were two really interesting optimizations that John explained:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Google Earth uses JavaScript &amp;lt;canvas&amp;gt; for correct text rendering&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Instead of trying to include a whole font/text engine in the WASM application, which would have been too big and too difficult to maintain, they instead rely on the web browser which can already do this. So to render text, the app draws the text into a JS canvas, reads it back, and then renders that inside of the 3D Google Earth scene.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XLC2qG_6GHnrKFm9NjHPYA.png" /&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;2. Runtime performance was significantly improved by doing a directly copy from &amp;lt;canvas&amp;gt; to a WebGL texture&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;What they were initially doing for the text rendering was:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Draw into a canvas&lt;/li&gt;&lt;li&gt;Read the canvas as bytes, send it to the WASM app&lt;/li&gt;&lt;li&gt;WASM app creates a WebGL texture with these bytes, and uploads it to the GPU&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To speed this up, they:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Draw into a canvas&lt;/li&gt;&lt;li&gt;Copy the canvas image data directly to a WebGL texture, give the WASM app a reference to that texture&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That reduced a lot of FPS jank.&lt;/p&gt;&lt;p&gt;An example of this kind of direct copy in WebGPU, see: &lt;a href="https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopyexternalimage"&gt;https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopyexternalimage&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;Q&amp;amp;A&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;There was a lot of interesting discussion at the Q&amp;amp;A at the end. One question in particular that stood out to me was on&lt;strong&gt; whether we can expect a “devtools” debugger/inspector for WebGPU&lt;/strong&gt;. It sounded like the answer was yes, there’s a lot of interest both from the WebGPU spec writers and the browser vendors for providing good debugging tools.&lt;/p&gt;&lt;p&gt;Kelsey mentioned debug groups &amp;amp; labels which is one tool that WebGPU has today that allows you to label parts of your pipeline to make it easier to debug when things go wrong. You can read more about it here: &lt;a href="https://gpuweb.github.io/gpuweb/explainer/#errors-errorscopes-labels"&gt;https://gpuweb.github.io/gpuweb/explainer/#errors-errorscopes-labels&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Ken closed out the session answering a question about how WebGPU is going to raise the bar of performance of realtime graphics on the web much closer to native applications.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;“The future is bright,”&lt;/strong&gt; he said. And I agree!&lt;/p&gt;&lt;p&gt;I hope you found this useful! You can &lt;a href="https://twitter.com/Omar4ur"&gt;find me on Twitter&lt;/a&gt; or on &lt;a href="https://omarshehata.me/"&gt;my website&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can sign up to be notified of the future WebGL/WebGPU meetups here: &lt;a href="https://www.khronos.org/news/subscribe/"&gt;https://www.khronos.org/news/subscribe/&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=d29f9e0d0bdc" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>Better outline rendering using surface IDs with WebGL</title>
            <link>https://omar-shehata.medium.com/better-outline-rendering-using-surface-ids-with-webgl-e13cdab1fd94?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/e13cdab1fd94</guid>
            <category>programming</category>
            <category>shaders</category>
            <category>webgl</category>
            <category>javascript</category>
            <category>threejs</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Tue, 11 Oct 2022 09:23:13 GMT</pubDate>
            <ns1:updated>2022-11-20T12:31:08.748Z</ns1:updated>
            <description>&lt;p&gt;This article builds on my previous &lt;a href="https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9"&gt;“How to render outlines in WebGL”&lt;/a&gt; tutorial. I’ll explain an improved technique that eliminates most artifacts of the previous article, and gives you more control over where exactly the lines are drawn in your geometry.&lt;/p&gt;&lt;p&gt;Below is an example of the artifacts with the previous technique (left) on the windows of the ship that are fixed using the newer method (right).&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DlDYyPqQWqGJboaCW4O2PA.gif" /&gt;&lt;/figure&gt;&lt;p&gt;I learned about this from &lt;a href="https://twitter.com/ianmaclarty/status/1499494878908403712"&gt;Ian MacLarty’s twitter thread&lt;/a&gt; about how outline rendering works in &lt;em&gt;Mars First Logistics:&lt;/em&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/0*IEkXfB-HXlwRb32d" /&gt;&lt;figcaption&gt;&lt;a href="https://store.steampowered.com/app/1532200/Mars_First_Logistics/"&gt;Screenshot from Mars First Logistics.&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3&gt;Live demo &amp;amp; source code&lt;/h3&gt;&lt;p&gt;Try out this outline rendering implementation in the demo below. You can drag and drop your own models into the viewer (as a single .glb/glTF file) or log in with Sketchfab and paste a model URL.&lt;/p&gt;&lt;p&gt;&lt;a href="https://threejs-outlines-postprocess.glitch.me/"&gt;https://threejs-outlines-postprocess.glitch.me/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Source code for this demo: &lt;a href="https://github.com/OmarShehata/webgl-outlines/tree/main/threejs"&gt;https://github.com/OmarShehata/webgl-outlines/tree/main/threejs&lt;/a&gt;&lt;/p&gt;&lt;p&gt;See also a minimal version without any of the debug parameters: &lt;a href="https://github.com/OmarShehata/webgl-outlines/tree/main/threejs-outlines-minimal"&gt;https://github.com/OmarShehata/webgl-outlines/tree/main/threejs-outlines-minimal&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;How it works — an overview&lt;/h3&gt;&lt;p&gt;The previous technique uses a combination of the normals &amp;amp; depth of the scene to detect edges in a post process pass. The new technique uses “surface IDs” instead of the normals.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ow1TJIEaKciLmU1tbrNAeA.png" /&gt;&lt;figcaption&gt;Pipeline image from the previous&lt;a href="https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9"&gt; “How to render outlines in WebGL”&lt;/a&gt; article&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;We compute surface IDs for each mesh at startup time (or offline). We assign a globally unique ID for each “surface” of a mesh (more on that below). These ID’s are stored as a vertex attribute, rendered to a buffer, and used as an input for the edge detection post process.&lt;/p&gt;&lt;p&gt;Here is a simple example where the normals are not sufficient to detect an edge:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/521/1*Pna6cZY_zP8u7hquyUxUkA.gif" /&gt;&lt;/figure&gt;&lt;p&gt;The front face of the box has the same normal as the wall behind it, so we can’t detect edges in certain camera angles where they align.&lt;/p&gt;&lt;p&gt;Now let’s take a look at the version where each surface has a unique ID (here I’m visualizing these ID’s by assigning a unique color to each one):&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/521/1*r29DeYA1kwu--Ybpr1Trjg.gif" /&gt;&lt;/figure&gt;&lt;p&gt;We can always detect an edge here.&lt;/p&gt;&lt;p&gt;Looking back at the ship example, we can see that this is why the outlines disappear on the windows of the ship as it rotates. Below is the normal buffer visualized on the left, and the surface IDs buffer visualized on the right:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZWTCFPToyZphE57k675QLA.gif" /&gt;&lt;/figure&gt;&lt;p&gt;The normals of the window interior align with the body of the ship for a few frames, so we are no longer able to detect an edge, while the depth difference isn’t sufficient to detect the edge either.&lt;/p&gt;&lt;p&gt;Whereas with the surface IDs, the two surfaces always have distinct values assigned to them, regardless of the camera angles.&lt;/p&gt;&lt;h3&gt;How to compute surface IDs of a mesh&lt;/h3&gt;&lt;p&gt;Ian MacLarty defines a surface as “a set of vertices that share triangles”. That means what we’re doing here is looking for all connected components in our mesh and assigning each a unique ID.&lt;/p&gt;&lt;p&gt;Let’s see how this works on a simple example. Here I have a cube in Blender with the top face selected, and the index of each vertex shown.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/646/1*zR3943u3QdSDxSgsK4n80A.png" /&gt;&lt;/figure&gt;&lt;p&gt;The top face of the cube is made of 2 triangles, and 6 vertices. The vertices “1” and “2” are shared between these two triangles, so we consider them part of the same “surface”.&lt;/p&gt;&lt;p&gt;If we take a look at another face of the cube, we’ll see that they do NOT share any vertices with the top face:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/666/1*jl36arqHebAXgVRsY_vVNw.png" /&gt;&lt;/figure&gt;&lt;p&gt;This means vertices “4” and “1” both sit right on top of each other, and so do “5” and “0”.&lt;/p&gt;&lt;p&gt;Why is the cube constructed this way? We technically only need to define 8 vertices total for this cube if we removed all duplicate vertices that are on top of each other like this. Instead, this cube has a total of 24 vertices (each face has 4 distinct vertices, and we have 6 faces).&lt;/p&gt;&lt;p&gt;The reason geometry is often constructed this way is because it allows us to define normals that are stored at each vertex. Vertices 0 and 1 have normals that point up, and vertices 4 and 5 have normals that point sideways.&lt;/p&gt;&lt;p&gt;Below are the normals visualized with the cube having 24 vertices (left) and if we combined them into 8 vertices (right). We can’t store all the normals correctly in the version on the right.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/748/1*IprF36YDtzqm5VaRO1iARQ.png" /&gt;&lt;/figure&gt;&lt;p&gt;Going back to our goal of finding distinct surfaces on the mesh: we’re using the fact that any triangles that are physically connected &amp;amp; face the same direction can all share vertices. So if we treat our mesh as a graph, with edges as links that connect vertices, then we can traverse this graph looking for connected components. This is what the &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/a36eb74e2cb7b318666f410861e4cbcd0e92134c/threejs/src/FindSurfaces.js#L42"&gt;FindSurfaces.js&lt;/a&gt; class does.&lt;/p&gt;&lt;p&gt;One important caveat here is the word “can” in the sentence: “any triangles that are physically connected &amp;amp; face the same direction &lt;strong&gt;CAN &lt;/strong&gt;all share vertices”. It’s entirely possible that your mesh has triangles that should be sharing vertices but are not. In that case a false edge will be rendered. We’ll look at this case in the “Tweaking your geometry” section below.&lt;/p&gt;&lt;h3&gt;Using the surface IDs in the edge detection post process&lt;/h3&gt;&lt;p&gt;Once we have the surface ID’s assigned to each vertex, we store them as a vertex attribute. We then have a render pass to render all surface ID’s in the scene to a buffer.&lt;/p&gt;&lt;p&gt;When drawing surface ID’s to the screen, I found the best results are achieved by:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Normalizing them between 0 and 1&lt;/li&gt;&lt;li&gt;Writing it to a float texture&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I found a texture type of HalfFloat to be sufficient precision. The shader for writing the surfaceID to a buffer can be found in &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/a36eb74e2cb7b318666f410861e4cbcd0e92134c/threejs/src/FindSurfaces.js#L164"&gt;FindSurfaces.js&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In the edge detect post process, once we detect a non-zero difference between the surface ID value of one pixel to its neighbors, we consider that an edge. This happens in &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/a36eb74e2cb7b318666f410861e4cbcd0e92134c/threejs-outlines-minimal/src/CustomOutlinePass.js#L191"&gt;CustomOutinePass.js&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The FindSurfaces class keeps track of a “max surface ID” that is set as a uniform when rendering the surface ID buffer so that normalizing the surfaceID happens in the shader. This allows new geometry to be added to the scene dynamically without having to go back and update the vertex attributes of all existing geometry.&lt;/p&gt;&lt;h3&gt;Tweaking your geometry for outline rendering&lt;/h3&gt;&lt;p&gt;Because this method of detecting edges relies on how the geometry is constructed, you may find artifacts caused by how your geometry is constructed.&lt;/p&gt;&lt;p&gt;To me this is one of the biggest advantages of this technique: you have very fine control over exactly which edges in your model should be part of the outline rendering when authoring it. You don’t have to fiddle with your edge detection parameters that may fix one case in one model but produce artifacts in another model. It is extra effort to fix these by hand but it’s a good tradeoff for getting high quality outline results.&lt;/p&gt;&lt;p&gt;Let’s take a look at an example using the &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/main/threejs/public/Tugboat.glb"&gt;Tugboat model&lt;/a&gt; (originally from Google Poly). Originally the windows looked like this:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/883/1*aeIWT4bwXz9-zB0UMCYPbg.png" /&gt;&lt;/figure&gt;&lt;p&gt;We’re seeing the 2 triangles that make up the windows, instead of the whole thing as one square. We can verify that this is a geometry problem by looking at the “Surface ID debug buffer” mode which shows us a unique color for each surface ID:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/883/1*pXSo-xJ7MFj6S4GsOLAkcg.png" /&gt;&lt;/figure&gt;&lt;p&gt;We want both triangles in the windows to have the same surface ID.&lt;/p&gt;&lt;p&gt;All we need to do is merge the vertices for these 2 triangles. I’ve had some trouble figuring out the best way to do this in Blender (even if I merge the vertices, the exported glTF often still has separate vertices for the triangles). My current method is to merge the triangles themselves:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Select the two (or more) faces in edit mode that should be considered one surface&lt;/li&gt;&lt;/ol&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/933/1*vLKTkzvjDZk7-vaWu4mPLg.png" /&gt;&lt;/figure&gt;&lt;p&gt;2. Switch to vertex mode to automatically selected all the vertices attached to those faces&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/919/1*ELKLIS4SfWE4qwsYVX3eVg.png" /&gt;&lt;/figure&gt;&lt;p&gt;3. Press “M” to merge vertices, select “By Distance”. The distance can be very small since we only want to merge vertices that are right on top of each other&lt;/p&gt;&lt;p&gt;4. Finally, switch back to face selection mode, right click on the selected face, and click “&lt;strong&gt;Dissolve faces&lt;/strong&gt;”. This combines the 2 triangles in each window into one face, and ensures each window gets 1 surface ID computed.&lt;/p&gt;&lt;h3&gt;Notes on other ways to compute surface IDs&lt;/h3&gt;&lt;p&gt;Instead of manually fixing your geometry by merging vertices, you could pre-compute and bake in a value in your model authoring workflow.&lt;/p&gt;&lt;p&gt;&lt;a href="https://twitter.com/csims314/status/1482123212188180490"&gt;Christopher Sims talks about his method&lt;/a&gt; of getting perfect outlines by using a Blender add on called &lt;a href="https://blendermarket.com/products/idmapper"&gt;IDMapper&lt;/a&gt;. This lets you bake in unique IDs across your mesh as vertex colors, and also makes it easy to edit them. I believe this is partially automatically generated.&lt;/p&gt;&lt;p&gt;What I’d love to see is a completely automatic method that lets you mark surfaces based on a threshold, in the same way the &lt;a href="https://threejs.org/docs/#api/en/geometries/EdgesGeometry"&gt;ThreeJS EdgesGeometry works&lt;/a&gt;. That class looks over all triangles, and checks the angle they make with the triangles they’re connected to. You could use that information to merge vertices for triangles that are all relatively flat. And you’d be able to tweak this threshold per model.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Edit: I’ve put together a tool to automate this, but turns out automation some drawbacks, namely texture coordinates may get distorted: &lt;/em&gt;&lt;a href="https://github.com/OmarShehata/webgl-outlines/tree/main/vertex-welder#vertex-welder"&gt;&lt;em&gt;https://github.com/OmarShehata/webgl-outlines/tree/main/vertex-welder#vertex-welder&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In any case I think it’s clear that the best outline results come from methods that do some form of geometry processing instead of relying just on screen space information, since that can be much more consistent across camera angles while also giving you more control over all edge cases (pun intended).&lt;/p&gt;&lt;p&gt;Thanks for reading! If you found this helpful, &lt;a href="https://omarshehata.me/notebook/my_newsletter"&gt;sign up to my newsletter&lt;/a&gt; to follow my work &amp;amp; stay in touch.&lt;/p&gt;&lt;p&gt;If you have any suggestions or corrections to the code or technique, open an issue on GitHub (&lt;a href="https://github.com/OmarShehata/webgl-outlines/"&gt;https://github.com/OmarShehata/webgl-outlines/&lt;/a&gt;) or reach out to me directly. You can find my contact info at: &lt;a href="https://omarshehata.me/"&gt;https://omarshehata.me/&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=e13cdab1fd94" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>How to use WebGPU Timestamp Query</title>
            <link>https://omar-shehata.medium.com/how-to-use-webgpu-timestamp-query-9bf81fb5344a?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/9bf81fb5344a</guid>
            <category>web</category>
            <category>gpu</category>
            <category>graphics-programming</category>
            <category>webgpu</category>
            <category>computer-graphics</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Mon, 29 Aug 2022 09:44:10 GMT</pubDate>
            <ns1:updated>2022-11-10T18:41:54.524Z</ns1:updated>
            <description>&lt;p&gt;This tutorial covers how to use WebGPU’s &lt;a href="https://www.w3.org/TR/webgpu/#dom-gpufeaturename-timestamp-query"&gt;timestamp query&lt;/a&gt; to measure how much time your GPU commands take to execute.&lt;/p&gt;&lt;p&gt;Timestamp queries are an optional WebGPU feature and may not be supported in all implementations. At the time of writing it is currently disabled in browsers for security reasons (&lt;a href="https://github.com/gpuweb/gpuweb/issues/2218"&gt;see discussion here&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;em&gt;See also: &lt;/em&gt;&lt;a href="https://github.com/OmarShehata/webgpu-compute-rasterizer/blob/main/how-to-use-timestamp-queries.md"&gt;&lt;em&gt;GitHub version of this tutorial&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/892/0*bQdol4ORggrJfZsx.png" /&gt;&lt;/figure&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;Below is a summary of the workflow for using timestamp queries:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Request access to timestamp-query when initializing the device&lt;/li&gt;&lt;li&gt;Create a query set with capacity N (number of timestamps you want to store in a frame)&lt;/li&gt;&lt;li&gt;Create a storage buffer with size N * 8. This is where the timestamp results are stored in nanoseconds, 64 bit numbers.&lt;/li&gt;&lt;li&gt;Record timestamps by calling &lt;a href="https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-writetimestamp"&gt;commandEncoder.writeTimestamp&lt;/a&gt;. This will record a timestamp after all previous commands have finished.&lt;/li&gt;&lt;li&gt;Call &lt;a href="https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-resolvequeryset"&gt;commandEncoder.resolveQuerySet&lt;/a&gt; to write the recorded timestamps to the storage buffer&lt;/li&gt;&lt;li&gt;Copy the results from the storage buffer to the CPU and decode them as a BigInt64Array (see &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt"&gt;BigInt&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Example: you want to measure how long it takes to render all transparent objects in your scene. You would write 1 timestamp &lt;strong&gt;before &lt;/strong&gt;any transparent draw calls, then a 2nd timestamp &lt;strong&gt;after &lt;/strong&gt;all the transparent draw calls, then compute the difference.&lt;/p&gt;&lt;h3&gt;Step by step guide&lt;/h3&gt;&lt;p&gt;A full example implementation can be found in this PR: &lt;a href="https://github.com/OmarShehata/webgpu-compute-rasterizer/pull/5/files"&gt;https://github.com/OmarShehata/webgpu-compute-rasterizer/pull/5/files&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;0 — Enable timestamp queries&lt;/h4&gt;&lt;p&gt;Launch Chrome with the following command line flag:&lt;/p&gt;&lt;pre&gt;--disable-dawn-features=disallow_unsafe_apis&lt;/pre&gt;&lt;h4&gt;1 — Queryset &amp;amp; buffer setup&lt;/h4&gt;&lt;p&gt;First we add timestamp-query to the list of required features when requesting the device:&lt;/p&gt;&lt;pre&gt;const device = await adapter.requestDevice({&lt;br&gt;	requiredFeatures: [&amp;quot;timestamp-query&amp;quot;],&lt;br&gt;});&lt;/pre&gt;&lt;p&gt;This will throw with the following error if it’s not enabled/supported:&lt;/p&gt;&lt;pre&gt;Uncaught (in promise) TypeError: Failed to execute &amp;#39;requestDevice&amp;#39; on &amp;#39;GPUAdapter&amp;#39;: Unsupported feature: timestamp-query&lt;/pre&gt;&lt;p&gt;Then we create a query set and a query buffer:&lt;/p&gt;&lt;pre&gt;const capacity = 3;//Max number of timestamps we can store&lt;br&gt;const querySet = device.createQuerySet({&lt;br&gt;	type: &amp;quot;timestamp&amp;quot;,&lt;br&gt;	count: capacity,&lt;br&gt;});&lt;br&gt;const queryBuffer = device.createBuffer({&lt;br&gt;	size: 8 * capacity,&lt;br&gt;	usage: GPUBufferUsage.QUERY_RESOLVE &lt;br&gt;	  | GPUBufferUsage.STORAGE&lt;br&gt;	  | GPUBufferUsage.COPY_SRC&lt;br&gt;	  | GPUBufferUsage.COPY_DST,&lt;br&gt;});&lt;/pre&gt;&lt;h4&gt;2 — Write timestamps&lt;/h4&gt;&lt;p&gt;We call &lt;a href="https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-writetimestamp"&gt;commandEncoder.writeTimestamp(querySet, index)&lt;/a&gt; at any point in the pipeline where we want to record a timestamp:&lt;/p&gt;&lt;pre&gt;// Add timestamps in between GPU commands&lt;br&gt;commandEncoder.writeTimestamp(querySet, 0);// Initial timestamp&lt;br&gt;// commandEncoder.draw(...)&lt;br&gt;commandEncoder.writeTimestamp(querySet, 1);&lt;/pre&gt;&lt;p&gt;The index must be less than or equal to capacity - 1 that we defined earlier.&lt;/p&gt;&lt;h4&gt;3 — Resolve timestamps to buffer&lt;/h4&gt;&lt;p&gt;At the end of your frame, call &lt;a href="https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-resolvequeryset"&gt;commandEncoder.resolveQuerySet&lt;/a&gt; to actually write the timestamps to the storage buffer:&lt;/p&gt;&lt;pre&gt;commandEncoder.resolveQuerySet(&lt;br&gt;	querySet, &lt;br&gt;	0,// index of first query to resolve &lt;br&gt;	capacity,//number of queries to resolve&lt;br&gt;	queryBuffer, &lt;br&gt;	0);// destination offset&lt;/pre&gt;&lt;h4&gt;4 — Read the results&lt;/h4&gt;&lt;p&gt;To get the timestamp results we need to copy the queryBuffer data to the CPU. Reading from a WebGPU buffer is explained in more detail here: &lt;a href="https://web.dev/gpu-compute/#commands-submission"&gt;https://web.dev/gpu-compute/#commands-submission&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Once you have the buffer data, you decode it as a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt"&gt;BigInt&lt;/a&gt; typed array. The timestamps are recorded in nanoseconds.&lt;/p&gt;&lt;pre&gt;// === After `commandEncoder.finish()` is called ===&lt;br&gt;// Read the storage buffer data&lt;br&gt;const arrayBuffer = await readBuffer(device, queryBuffer);&lt;br&gt;// Decode it into an array of timestamps in nanoseconds&lt;br&gt;const timingsNanoseconds = new BigInt64Array(arrayBuffer);&lt;/pre&gt;&lt;pre&gt;// ....&lt;/pre&gt;&lt;pre&gt;async function readBuffer(device, buffer) {&lt;br&gt;  const size = buffer.size;&lt;br&gt;  const gpuReadBuffer = device.createBuffer({size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ });&lt;/pre&gt;&lt;pre&gt;  const copyEncoder = device.createCommandEncoder();&lt;br&gt;  copyEncoder.copyBufferToBuffer(buffer, 0, gpuReadBuffer, 0, size);&lt;/pre&gt;&lt;pre&gt;  const copyCommands = copyEncoder.finish();&lt;br&gt;  device.queue.submit([copyCommands]);&lt;/pre&gt;&lt;pre&gt;  await gpuReadBuffer.mapAsync(GPUMapMode.READ);&lt;br&gt;  return gpuReadBuffer.getMappedRange();&lt;br&gt;}&lt;/pre&gt;&lt;h4&gt;(Optional) 5 — Create labels&lt;/h4&gt;&lt;p&gt;To make the output more useful, we can define labels for each timestamp we collect, and then print out the diff so we can see the time it took for each step in our pipeline. It may also be useful to convert the result to milliseconds.&lt;/p&gt;&lt;p&gt;This is implemented in the reference example here: &lt;a href="https://github.com/OmarShehata/webgpu-compute-rasterizer/pull/5/files"&gt;https://github.com/OmarShehata/webgpu-compute-rasterizer/pull/5/files&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hope you found this helpful! &lt;/em&gt;&lt;a href="https://omarshehata.me/notebook/my_newsletter"&gt;Sign up to my newsletter&lt;/a&gt; to follow WebGL/WebGPU writing &amp;amp; stay in touch.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Big thanks to Markus Schütz whose &lt;/em&gt;&lt;a href="https://github.com/m-schuetz/Potree2/blob/299b22ef59bb1eaebc8862d37ac86ae8800d5b6a/src/renderer/Timer.js"&gt;&lt;em&gt;Potree implementation WebGPU implementation&lt;/em&gt;&lt;/a&gt;&lt;em&gt; provided a great example of how to use timestamp queries. &lt;/em&gt;&lt;a href="https://github.com/gpuweb/gpuweb/discussions/3354"&gt;&lt;em&gt;Thanks to Yang Gu&lt;/em&gt;&lt;/a&gt;&lt;em&gt; for explaining how to enable it in Chrome.&lt;/em&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=9bf81fb5344a" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>WebGL / WebGPU April 2022 meetup highlights</title>
            <link>https://omar-shehata.medium.com/webgl-webgpu-april-2022-meetup-highlights-e57ad07e1f60?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/e57ad07e1f60</guid>
            <category>webgpu</category>
            <category>graphics-programming</category>
            <category>javascript</category>
            <category>web</category>
            <category>webgl</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Sun, 01 May 2022 19:58:16 GMT</pubDate>
            <ns1:updated>2022-05-01T19:58:16.952Z</ns1:updated>
            <description>&lt;p&gt;The &lt;a href="https://www.khronos.org/events/webgl-meetup-april-2022"&gt;Khronos WebGL/WebGPU meetup&lt;/a&gt; is a recurring event where the folks working on these web graphics API’s share updates followed by talks from the community.&lt;/p&gt;&lt;p&gt;I’ve summarized highlights from April’s event in this article.&lt;/p&gt;&lt;p&gt;&lt;em&gt;For my past event recaps, see &lt;/em&gt;&lt;a href="https://omar-shehata.medium.com/webgpu-january-2022-meetup-takeaways-4cbe03d088b1"&gt;&lt;em&gt;January 2022&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, &lt;/em&gt;&lt;a href="https://omar-shehata.medium.com/my-takeaways-from-webgpu-july-2021-meetup-8c27244e8b8f?source=your_stories_page-------------------------------------"&gt;&lt;em&gt;July 2021&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h4&gt;WebGL and WebGPU Updates&lt;/h4&gt;&lt;p&gt;Ken Russell — Google&lt;br&gt;Kelsey Gilbert — Mozilla&lt;br&gt;&lt;a href="https://www.khronos.org/developers/linkto/webgl-and-webgpu-updates"&gt;Slides&lt;/a&gt;&lt;br&gt;&lt;a href="https://youtu.be/dpfJRxZgJN8?t=81"&gt;Timestamp, 1:20&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Wide color gamut support&lt;/strong&gt; for WebGL is being implemented in Chrome &amp;amp; Firefox (example: P3 support, &lt;a href="https://github.com/WICG/canvas-color-space/blob/main/CanvasColorSpaceProposal.md"&gt;see proposal here&lt;/a&gt;). I believe this is planned for WebGPU in the future, &lt;a href="https://github.com/gpuweb/gpuweb/discussions/2537#discussioncomment-2053513"&gt;see discussion here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Lots of recent &lt;strong&gt;Firefox WebGL updates&lt;/strong&gt;, most notably support for OffscreenCanvas (enables real multithreaded WebGL, can render on workers)&lt;/li&gt;&lt;li&gt;Chrome &amp;amp; Safari working to switch to &lt;strong&gt;Metal backend&lt;/strong&gt;. You can test Chrome with Metal today (set “Choose ANGLE graphics backend” to “Metal” in about:flags). Report bugs in the&lt;a href="https://bugs.chromium.org/p/angleproject/issues/list"&gt; ANGLE issue tracker&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Current &lt;strong&gt;WebGPU 1.0 spec&lt;/strong&gt; release is targeted for Q3 2022. Breaking changes are still expected. Main things they’re working on now are updates to the shading language (reducing verbosity, adding features requested by community etc), privacy &amp;amp; security, and conformance tests.&lt;/li&gt;&lt;li&gt;Ways to &lt;strong&gt;contribute to WebGPU&lt;/strong&gt;: (1) use the API and report bugs. (2) &lt;a href="https://github.com/gpuweb/cts/blob/main/docs/intro/README.md"&gt;Write conformance tests &lt;/a&gt;(great way to learn WebGPU) (3) contribute samples/demo&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can get in touch with the folks working on the WebGPU spec through (1) &lt;a href="https://github.com/gpuweb/gpuweb"&gt;the GitHub repo&lt;/a&gt; (2) the &lt;a href="https://matrix.to/#/#WebGPU:matrix.org"&gt;Matrix chat room&lt;/a&gt;. Ken &amp;amp; Kelsey emphasized that questions, feedback, and contributions are welcome!&lt;/p&gt;&lt;p&gt;One of the new WebGPU resources Kelsey shared was&lt;strong&gt; Tim Jones’ shader playground&lt;/strong&gt;: &lt;a href="https://shader-playground.timjones.io/"&gt;https://shader-playground.timjones.io/&lt;/a&gt;. This lets you see the output of various shader compilers, or see how GLSL -&amp;gt; WGSL transpiling works. It can be a useful tool for learning or debugging.&lt;/p&gt;&lt;p&gt;Below is an example of a GLSL snippet transpiled to WGSL using &lt;a href="https://github.com/gfx-rs/naga"&gt;Naga&lt;/a&gt;.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SaaqTfO5rhTQSbbxlBSVJQ.png" /&gt;&lt;/figure&gt;&lt;h4&gt;Intel’s Updates on Web Graphics&lt;/h4&gt;&lt;p&gt;Yang Gu — Intel Web Graphics Team&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/Intel_updates_Yang_Gu_Apr22.pdf"&gt;Slides&lt;/a&gt;&lt;br&gt;&lt;a href="https://youtu.be/dpfJRxZgJN8?t=1125"&gt;Timestamp, 18:45&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Yang talked about Intel’s contributions to web graphics, dating back to Nov 2011. Their recent focus has been on WebGPU, and &lt;strong&gt;TensorFlow.js’s WebGPU backend&lt;/strong&gt;.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/999/1*Iwuc02p6YhACm2T6oz_fWw.png" /&gt;&lt;/figure&gt;&lt;p&gt;The Intel Web Graphics team are currently the maintainers of the TensorFlow.js’s WebGPU backend. He mentioned that they are &lt;strong&gt;already seeing better performance than the WebGL backend&lt;/strong&gt; with medium &amp;amp; large size models.&lt;/p&gt;&lt;p&gt;Yang also mentioned that there is a large community of web graphics developers in China and that they are trying to grow this community. If you’re interested in that, Yang Gu’s contact is in the slide below.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1020/1*yGE5HYmb-ckQ8C0E-l-dVw.png" /&gt;&lt;/figure&gt;&lt;h4&gt;3D Tiles Next: Bringing massive 3D geospatial data to the web&lt;/h4&gt;&lt;p&gt;Sean Lilley — Cesium&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/3D_Tiles_Next_Sean_Lilly_Apr22.pdf"&gt;Slides&lt;/a&gt;&lt;br&gt;&lt;a href="https://youtu.be/dpfJRxZgJN8?t=1707"&gt;Timestamp, 28:25&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Sean talked about 3D Tiles, a format used for visualizing &amp;amp; storing 3D geospatial data. He explained that it’s a “spatial data structure for glTF, where each tile is a glTF. It allows you to&lt;strong&gt; stream in only what’s needed for a given view&lt;/strong&gt;”.&lt;/li&gt;&lt;li&gt;3D Tiles Next is an upcoming revision of this format that has (1) better support for metadata (2) and a cleaner integration with the glTF ecosystem, which makes it easier to use 3D Tiles in engines that support glTF.&lt;/li&gt;&lt;li&gt;The Cesium team has been working on&lt;strong&gt; 2 new glTF extensions&lt;/strong&gt; to support this: (1) &lt;a href="https://github.com/KhronosGroup/glTF/pull/2082"&gt;EXT_mesh_features&lt;/a&gt; (2) &lt;a href="https://github.com/KhronosGroup/glTF/pull/2151"&gt;EXT_structural_metadata&lt;/a&gt;. Together these extensions allow you to embed rich metadata into glTF models while still allowing you to combine &amp;amp; batch geometry for fast rendering.&lt;/li&gt;&lt;li&gt;Sean covered a little bit about how the CesiumJS renderer works. How they handle global scale precision, how they batch draw calls for fast rendering, and how they handle picking features in city scale datasets.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Below is an example of the metadata support Sean mentioned. The glTF nodes in this 3D Tileset have a “feature ID texture”, that allows the engine to look up properties associated with a particular point on the mesh. This is often used to encode information from an AI model (like that it classified it as a window, or a door etc) or information from the sensors that capture &amp;amp; generated this model (such as accuracy, camera angle, etc).&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1018/1*cRcnVzq7-o4Itv2DFRnFoA.png" /&gt;&lt;/figure&gt;&lt;h4&gt;Creative RAM Savings in WebGL&lt;/h4&gt;&lt;p&gt;Toni Martí — Tribia&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/GPU_RAM_Savings_Toni_Marti_Apr22.pdf"&gt;Slides&lt;/a&gt;&lt;br&gt;&lt;a href="https://youtu.be/dpfJRxZgJN8?t=3021"&gt;Timestamp, 50:21&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Toni shared his &lt;strong&gt;“data textures”&lt;/strong&gt; technique for aggressively&lt;strong&gt; reducing GPU-RAM&lt;/strong&gt; consumption in WebGL (by about 80% in his application)&lt;/li&gt;&lt;li&gt;He implemented this in &lt;strong&gt;xeokit &lt;/strong&gt;— a viewer for high precision 3D engineering &amp;amp; BIM models on the web&lt;/li&gt;&lt;li&gt;The basic idea is using &lt;strong&gt;NO vertex attributes&lt;/strong&gt;. Instead, all vertices, colors etc are written to textures. This uses significantly less memory because color data doesn’t need to be repeated for all vertices that use it. This also makes it faster to update.&lt;/li&gt;&lt;li&gt;He covered the implementation of this&lt;a href="https://github.com/xeokit/xeokit-sdk/pull/824"&gt; technique in this PR&lt;/a&gt;. Specifically, &lt;a href="https://github.com/tribiahq/xeokit-sdk/blob/acc436de6784b31f1982a6c190397f8fa202dfce/src/viewer/scene/PerformanceModel/lib/layers/trianglesDataTexture/renderers/TrianglesDataTextureColorRenderer.js#L264"&gt;see the vertex shader in TrianglesDataTextureColorRenderer.js&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Below is the demo he showed: 73k objects with individual color &amp;amp; position offsets that are updated 10 times per second.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/400/1*v98JYUdQ-GapW1n1k4guHw.gif" /&gt;&lt;/figure&gt;&lt;p&gt;I hope you found this useful! You can &lt;a href="https://twitter.com/Omar4ur"&gt;find me on Twitter&lt;/a&gt; or on &lt;a href="https://omarshehata.me/"&gt;my website&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can sign up to be notified of the future WebGL/WebGPU meetups here: &lt;a href="https://www.khronos.org/news/subscribe/"&gt;https://www.khronos.org/news/subscribe/&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=e57ad07e1f60" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>WebGPU January 2022 meetup — takeaways</title>
            <link>https://omar-shehata.medium.com/webgpu-january-2022-meetup-takeaways-4cbe03d088b1?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/4cbe03d088b1</guid>
            <category>graphics</category>
            <category>computer-graphics</category>
            <category>web</category>
            <category>webgl</category>
            <category>webgpu</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Tue, 01 Feb 2022 21:12:01 GMT</pubDate>
            <ns1:updated>2022-02-01T21:12:01.440Z</ns1:updated>
            <description>&lt;h3&gt;WebGPU January 2022 meetup — takeaways&lt;/h3&gt;&lt;p&gt;The WebGL/WebGPU January talk is up (&lt;a href="https://www.youtube.com/watch?v=wYAvVUFQP2M"&gt;https://www.youtube.com/watch?v=wYAvVUFQP2M&lt;/a&gt;)! I encourage you to watch full video.&lt;/p&gt;&lt;p&gt;I’ve compiled my takeaways here (with a focus on WebGPU) so you can skim the highlights &amp;amp; see links to resources mentioned by the speakers all in one place.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Event link where you can register for future meetups: &lt;/em&gt;&lt;a href="https://www.khronos.org/events/webgl-webgpu-meetup-january-2022"&gt;&lt;em&gt;https://www.khronos.org/events/webgl-webgpu-meetup-january-2022&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;General updates &amp;amp; new WebGL extensions&lt;/h4&gt;&lt;p&gt;Ken Russell (&lt;a href="https://twitter.com/gfxprogrammer"&gt;https://twitter.com/gfxprogrammer&lt;/a&gt;) &lt;br&gt;Kai Ninomiya (&lt;a href="https://twitter.com/kainino0x"&gt;https://twitter.com/kainino0x&lt;/a&gt;) &lt;br&gt;&lt;a href="https://www.khronos.org/developers/linkto/webgl-webgpu-updates-january-2022"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Ken encouraged everyone who works with or is interested in WebGPU to join the community! They welcome all feedback.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;See the &lt;strong&gt;WebGPU GitHub discussions&lt;/strong&gt;: &lt;a href="https://github.com/gpuweb/gpuweb/discussions/"&gt;https://github.com/gpuweb/gpuweb/discussions/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Also &lt;strong&gt;WebGPU matrix chat&lt;/strong&gt; &lt;a href="https://matrix.to/#/#WebGPU:matrix.org"&gt;https://matrix.to/#/#WebGPU:matrix.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;This repo is where the &lt;strong&gt;spec is being developed &amp;amp; discussed&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;WebGPU spec 1.0 release is currently targeting ~&lt;strong&gt;Q2 2022&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;You can &lt;strong&gt;release WebGPU apps on the web today without having users enable any special flags&lt;/strong&gt; by signing your website up for the origin trial (&lt;a href="https://web.dev/gpu/#register-for-ot"&gt;https://web.dev/gpu/#register-for-ot&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;There are currently many breaking changes as the spec rapidly develops. I was curious about these changes particularly with WGSL. &lt;a href="https://github.com/gpuweb/gpuweb/pulls?page=1&amp;amp;q=is%3Apr+is%3Aclosed+label%3Awgsl"&gt;Skimming the recent PRs&lt;/a&gt; you can find:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Adding increment/decrement operators . &lt;a href="https://github.com/gpuweb/gpuweb/pull/2342/"&gt;PR&lt;/a&gt;. &lt;a href="https://www.w3.org/TR/WGSL/#increment-decrement"&gt;Spec link&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Built in functions for converting to/from degrees &amp;amp; radians. &lt;a href="https://github.com/gpuweb/gpuweb/pull/2360"&gt;PR&lt;/a&gt;. &lt;a href="https://www.w3.org/TR/WGSL/#float-builtin-functions"&gt;Spec link&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It is exciting for me to see that such core language features are still being added at this stage, and that we as developers get to provide feedback &amp;amp; be a part of this process!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;WebGL 2 can now be considered universally supported!&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;This is largely thanks to WebGL 2 shipping on iOS/MacOS last year. It runs on Metal on all newer devices.&lt;/li&gt;&lt;li&gt;Safari team is rapidly fixing any WebGL 2 bugs. If you notice any please report it at &lt;a href="https://bugs.webkit.org/"&gt;https://bugs.webkit.org/&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Ken’s recommendation for most apps is that you no longer need to maintain a WebGL 1 fallback.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;New WebGL 2 extensions&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/"&gt;OES_draw_buffers_indexed&lt;/a&gt; — requested by 3D formats working group to implement advanced materials (eg using dual depth peeling). This allows you to use different blend options when writing to multiple color buffers simultaneously.&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.khronos.org/registry/webgl/extensions/WEBGL_draw_instanced_base_vertex_base_instance/"&gt;WEBGL_draw_instanced_base_vertex_base_instance&lt;/a&gt; — Reduces memory use by allowing reusing index buffer to draw multiple different geometries from the same set of vertex buffers. This is still a draft.&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.khronos.org/registry/webgl/extensions/WEBGL_multi_draw_instanced_base_vertex_base_instance/"&gt;WEBGL_multi_draw_instanced_base_vertex_base_instance&lt;/a&gt; — Same as above but for rendering more than 1 primitive with one draw call.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;WebGPU Best Practices&lt;/h4&gt;&lt;p&gt;Brandon Jones (&lt;a href="https://twitter.com/Tojiro"&gt;https://twitter.com/Tojiro&lt;/a&gt;)&lt;br&gt;&lt;a href="https://www.khronos.org/developers/linkto/webgpu-best-practices"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Brandon has written a couple of WebGPU best practice guides, like this one about uploading data to GPU buffers: &lt;a href="https://toji.github.io/webgpu-best-practices/buffer-uploads.html"&gt;https://toji.github.io/webgpu-best-practices/buffer-uploads.html&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This presentation covered this and a few other other topics I found incredibly useful:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use &lt;strong&gt;debug labels&lt;/strong&gt; to get helpful error messages: &lt;a href="https://gpuweb.github.io/gpuweb/explainer/#errors-errorscopes-labels"&gt;https://gpuweb.github.io/gpuweb/explainer/#errors-errorscopes-labels&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Use &lt;strong&gt;debug groups&lt;/strong&gt; so that error messages will tell you exactly where in the pipeline the failure occurred (like which render pass): &lt;a href="https://gpuweb.github.io/gpuweb/explainer/#command-encoding-debug"&gt;https://gpuweb.github.io/gpuweb/explainer/#command-encoding-debug&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Use &lt;strong&gt;compressed textures&lt;/strong&gt; (see &lt;a href="https://github.com/KhronosGroup/3D-Formats-Guidelines/blob/main/KTXArtistGuide.md"&gt;artist’s guide here&lt;/a&gt;). Brandon built a library to serve as a reference for loading different texture formats in WebGPU/WebGL: &lt;a href="https://github.com/toji/web-texture-tool"&gt;https://github.com/toji/web-texture-tool&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;gltf-transform has a CLI &lt;/strong&gt;for creating these compressed textures &amp;amp; applying other optimizations: &lt;a href="https://gltf-transform.donmccurdy.com/cli.html"&gt;https://gltf-transform.donmccurdy.com/cli.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Use async pipeline creation&lt;/strong&gt;. Otherwise users will experience jank when you use a pipeline that’s not ready.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Avoid implicit pipeline layouts&lt;/strong&gt;. Mainly so that you can re-use bind groups for different pipelines, which is the common scenario. For example you would have a bind group for your uniform buffer(s) that is re-used for all your shader pipelines.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;WSGL Editor&lt;/h4&gt;&lt;p&gt;Takahiro (&lt;a href="https://twitter.com/superhoge"&gt;https://twitter.com/superhoge&lt;/a&gt;)&lt;br&gt;Online demo: &lt;a href="https://takahirox.github.io/online-wgsl-editor/index.html"&gt;https://takahirox.github.io/online-wgsl-editor/index.html&lt;/a&gt;&lt;br&gt;Repo: &lt;a href="https://github.com/takahirox/online-wgsl-editor"&gt;https://github.com/takahirox/online-wgsl-editor&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;This is a ShaderToy-like environment but for WGSL &amp;amp; WebGPU&lt;/strong&gt;. The editor will show you any errors inline.&lt;/p&gt;&lt;p&gt;It’s really useful for learning &amp;amp; experimenting. You can move your mouse away from the screen to hide the code &amp;amp; just see the display. Contributions are welcome!&lt;/p&gt;&lt;p&gt;Takahiro demonstrated using this editor to modify a vertex shader &amp;amp; deform this cube:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/576/1*YuI0_F1qA47eh14bYdskgA.gif" /&gt;&lt;/figure&gt;&lt;h4&gt;Creative coding with WebGL 2&lt;/h4&gt;&lt;p&gt;Jaume Sanchez (&lt;a href="https://twitter.com/thespite"&gt;https://twitter.com/thespite&lt;/a&gt;)&lt;br&gt;Online demo: &lt;a href="https://spite.github.io/genuary-2022/"&gt;https://spite.github.io/genuary-2022/&lt;/a&gt;&lt;br&gt;Repo: &lt;a href="https://github.com/spite/genuary-2022"&gt;https://github.com/spite/genuary-2022&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Jaume presented incredibly beautiful work he did for Genuary (&lt;a href="https://genuary.art/"&gt;https://genuary.art/&lt;/a&gt;) that’s all open source.&lt;/p&gt;&lt;h3&gt;Jaume Sanchez Elias on Twitter: &amp;quot;#genuary 2022 - Day 21 - Combine two (or more) of your pieces from previous days to make a new piece.Day 4 + Day 16 = the DOFidenzamade with #threejs #genuary2022https://t.co/8RnqjSm0x3 pic.twitter.com/jUaYogaQGF / Twitter&amp;quot;&lt;/h3&gt;&lt;p&gt;genuary 2022 - Day 21 - Combine two (or more) of your pieces from previous days to make a new piece.Day 4 + Day 16 = the DOFidenzamade with #threejs #genuary2022https://t.co/8RnqjSm0x3 pic.twitter.com/jUaYogaQGF&lt;/p&gt;&lt;p&gt;It’s a great resource for learning lots of different techniques for procedurally generated effects like generating noise, using SDF’s (signed distance fields), volume rendering, non photorealistic rendering, and more.&lt;/p&gt;&lt;h4&gt;Clustered shading in PlayCanvas&lt;/h4&gt;&lt;p&gt;Donovan Hutchence (&lt;a href="https://twitter.com/slimbuck7"&gt;https://twitter.com/slimbuck7&lt;/a&gt;)&lt;br&gt;&lt;a href="https://www.khronos.org/developers/linkto/playcanvas-january-2022-update"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Donovan presented on how the PlayCanvas team recently added clustered lighting to the engine. He gave a great explanation of how it works including some stunning debug views you can see in the video clip in the tweet below.&lt;/p&gt;&lt;h3&gt;Will Eastcott on Twitter: &amp;quot;The @playcanvas engine repo was trending on GitHub last week. Maybe due to the clustered lighting tech we showed at @thekhronosgroup WebGL meetup. If u want to see how we did it:📜Repo: https://t.co/Tnf0ES1nDZ🖥️Slides: https://t.co/zJ7s4XWjpO📺Preso: https://t.co/H2F71X0hp9 pic.twitter.com/rfMSHAUewh / Twitter&amp;quot;&lt;/h3&gt;&lt;p&gt;The @playcanvas engine repo was trending on GitHub last week. Maybe due to the clustered lighting tech we showed at @thekhronosgroup WebGL meetup. If u want to see how we did it:📜Repo: https://t.co/Tnf0ES1nDZ🖥️Slides: https://t.co/zJ7s4XWjpO📺Preso: https://t.co/H2F71X0hp9 pic.twitter.com/rfMSHAUewh&lt;/p&gt;&lt;p&gt;I hope you found this useful! You can find me on Twitter (&lt;a href="https://twitter.com/Omar4ur"&gt;https://twitter.com/Omar4ur&lt;/a&gt;), I’d love to hear any thoughts.&lt;/p&gt;&lt;p&gt;If you’re interested in giving a talk at this meetup, reach out to them! From their event description:&lt;/p&gt;&lt;p&gt;&lt;em&gt;If you would like to be considered to present at one of our upcoming WebGL+ WebGPU Meetups, please reach out to &lt;/em&gt;&lt;a href="mailto:events@khronos.org"&gt;&lt;em&gt;events@khronos.org&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=4cbe03d088b1" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>My Takeaways from WebGPU July 2021 Meetup</title>
            <link>https://omar-shehata.medium.com/my-takeaways-from-webgpu-july-2021-meetup-8c27244e8b8f?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8c27244e8b8f</guid>
            <category>webgl</category>
            <category>javascript</category>
            <category>programming</category>
            <category>3d</category>
            <category>web</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Tue, 24 Aug 2021 19:34:49 GMT</pubDate>
            <ns1:updated>2021-08-25T13:27:18.048Z</ns1:updated>
            <description>&lt;p&gt;The last &lt;a href="https://www.khronos.org/events/webgl-webgpu-meetup-2021-07"&gt;WebGL / WebGPU meetup&lt;/a&gt; was packed with a lot of really exciting content. You can find the &lt;a href="https://www.youtube.com/watch?v=kZCqRlabZiU"&gt;full 90 minute recording here&lt;/a&gt;. I decided to put together my takeaways here for others who want a quick glimpse of the latest updates, focusing particularly on WebGPU.&lt;/p&gt;&lt;p&gt;You’ll find Youtube timestamps for each talk below if you’re interested in watching the full segment (which I highly recommend!)&lt;/p&gt;&lt;h4&gt;Advice for porting a large WebGL project to WebGPU&lt;/h4&gt;&lt;p&gt;&lt;em&gt;Jasper St. Pierre — Yacht Club Games.&lt;br&gt;&lt;/em&gt;&lt;a href="https://youtu.be/kZCqRlabZiU?t=363"&gt;&lt;em&gt;Timestamp: 6:02–21:25&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;br&gt;&lt;/em&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/Jasper-St.-Pierre---Porting-an-existing-WebGL-application-to-WebGPU_.pdf"&gt;&lt;em&gt;Slides&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q0vJJMKyJ7J5WGn0GQJHlw.png" /&gt;&lt;/figure&gt;&lt;p&gt;Jasper is the creator of the famous &lt;a href="https://noclip.website/"&gt;noclip.website&lt;/a&gt; — a custom web rendering implementation of many famous video game levels, like Mario Kart &amp;amp; Half Life.&lt;/p&gt;&lt;p&gt;He recently ported this engine to WebGPU. This acted as a really good testbed for the spec because his engine implements so many different games that all use a wide range of rendering techniques.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;WebGPU requires the use of uniform buffers&lt;/strong&gt;, which is one big difference with WebGL. You can’t define and update individual uniform values anymore. You put all your uniforms into a buffer and send that all at once, which is a more efficient use of modern GPU hardware.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Jasper recommends porting WebGL 1 -&amp;gt; WebGL 2 as an intermediate step&lt;/strong&gt;. Since WebGL 2 supports uniform buffers, and the code for binding is a little simpler.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Do not update uniform buffers between draw calls in WebGPU&lt;/strong&gt;. This may be a common pattern in WebGL 2, but you want to keep GPU memory untouched as long as possible so it can execute draw calls in parallel. Instead, &lt;strong&gt;he created one single large buffer&lt;/strong&gt;, containing data for all draw calls, and binding different parts of it before different draw calls.&lt;/li&gt;&lt;/ul&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/776/1*SYhKHw-XpsUx1JE--mmrVw.png" /&gt;&lt;/figure&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Jasper kept his shaders in GLSL and converts to WGSL at runtime&lt;/strong&gt; using &lt;a href="https://github.com/gfx-rs/naga"&gt;https://github.com/gfx-rs/naga&lt;/a&gt; using WebAssembly. WGSL stands for WebGPU Shading Language.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Viewport and clipspace conventions are different in WebGPU&lt;/strong&gt;. WebGPU has 0,0 in the top left (as opposed to bottom left). And the frustum in WebGPU is 1 to 0 (as opposed to 1 to -1). This was easy to account for.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Consider a “draw call objects” design for your renderer&lt;/strong&gt;. This one is more general advice: Instead of each object initiating draw calls directly, it pushes an object into a list containing info needed for the draw call. This makes it easier to handle multi pass rendering, sorting if needed for transparency, and collecting uniform data up front.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;No.clip website repo: &lt;a href="https://github.com/magcius/noclip.website"&gt;https://github.com/magcius/noclip.website&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The graphics framework behind it: &lt;a href="https://github.com/magcius/gfxrlz"&gt;https://github.com/magcius/gfxrlz&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;glTF Sampler Viewer&lt;/h4&gt;&lt;p&gt;Moritz Becher — UX3D&lt;a href="https://youtu.be/kZCqRlabZiU?t=1294"&gt;&lt;br&gt;Timestamp: 21:35–35:30&lt;/a&gt;&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/Moritz-Becher---glTF-Sample-Viewer.pdf"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/928/1*6N3KfdzIODIGDRiamkorGg.png" /&gt;&lt;/figure&gt;&lt;p&gt;glTF Sample Viewer (&lt;a href="https://github.khronos.org/glTF-Sample-Viewer-Release/"&gt;https://github.khronos.org/glTF-Sample-Viewer-Release/&lt;/a&gt;) is an open source web app that‘s really useful for (1) verifying your glTF implementation is correct (2) finding clean sample implementation of any part of the glTF spec (3) easily previewing glTF models by drag &amp;amp; drop.&lt;/p&gt;&lt;p&gt;Source code: &lt;a href="https://github.com/KhronosGroup/glTF-Sample-Viewer"&gt;https://github.com/KhronosGroup/glTF-Sample-Viewer&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;This is a “native glTF viewer” in that it uploads glTF resources/buffers directly to the GPU&lt;/strong&gt;, as opposed to parsing them into another intermediate format. .&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Always updated with the latest spec &amp;amp; extensions&lt;/strong&gt;. &lt;a href="https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/33971b2f0a869bc93f6673feac388167e4fd520a/source/Renderer/shaders/ibl.glsl#L52"&gt;For example, here you can find an implementation of the new volume transmission&lt;/a&gt; extension, which is useful since the spec doesn’t dictate a specific implementation.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;PBR &amp;amp; KTX extensions for glTF&lt;/h4&gt;&lt;p&gt;Sandra Voelker — Target&lt;br&gt;&lt;a href="https://youtu.be/kZCqRlabZiU?t=2140"&gt;Timestamp: 35:40–54:20&lt;/a&gt;&lt;br&gt;&lt;a href="https://www.khronos.org/developers/linkto/target-latest-gltf-extensions-advantages-to-tech-artists"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EYVRnufTa18md2OW3RBqrQ.png" /&gt;&lt;/figure&gt;&lt;p&gt;This talk was really interesting to see how a lot of the PBR (Physically Based Rendering) extensions for glTF are being pushed for by companies like Target &amp;amp; Wayfair for eCommerce purposes.&lt;/p&gt;&lt;p&gt;Some of those new extensions this year are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_sheen/README.md"&gt;KHR_materials_sheen&lt;/a&gt; — for representing the back-scattering of velvet-like materials (cloth &amp;amp; fabric generally).&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_specular/README.md"&gt;KHR_materials_specular&lt;/a&gt; — for representing specular color refraction (like how different rainbow-like colors can appear when looking through glass).&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_transmission/README.md"&gt;KHR_materials_transmission &lt;/a&gt;&amp;amp; &lt;a href="https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_volume/README.md"&gt;KHR_materials_volume&lt;/a&gt; — for translucent objects with non-uniform thickness like a glass jar.&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_basisu/README.md"&gt;KHR_texture_basisu&lt;/a&gt; — for texture compression with Basis Universal supercompression.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Since these extensions are new, not all 3D authoring programs support exporting them yet. Some tools Sandra recommended are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/BabylonJS/Exporters/#babylonjs-exporters"&gt;BabylonJS exporter for 3DS Max and Maya&lt;/a&gt;. This is a plugin that lets you export a glTF that uses these new PBR extensions&lt;/li&gt;&lt;li&gt;Sandra used Blender for exporting the vase with transparent glass. &lt;a href="https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html"&gt;See Blender glTF extensions doc&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Sandra used &lt;a href="https://www.adobe.com/creativecloud/3d-augmented-reality.html"&gt;the new Adobe Substance 3D&lt;/a&gt; to export cloth materials with the sheen extension.&lt;/li&gt;&lt;li&gt;Sandra used the &lt;a href="https://github.com/AnalyticalGraphicsInc/gltf-vscode#gltf-tools-extension-for-visual-studio-code"&gt;glTF VS Code plugin&lt;/a&gt; for adding the clear coat extension. This allows you to edit glTF material properties in realtime by editing the JSON file directly.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are many useful links at the end of Sandra’s slides, I wanted to call out in particular this “artist’s guide” for creating KTX materials which is really helpful for understanding how to get textures that use vastly less GPU memory and still look great: &lt;a href="https://github.com/KhronosGroup/3D-Formats-Guidelines/blob/main/KTXArtistGuide.md"&gt;https://github.com/KhronosGroup/3D-Formats-Guidelines/blob/main/KTXArtistGuide.md&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Gestaltor (&lt;a href="https://gestaltor.io/"&gt;https://gestaltor.io/&lt;/a&gt;) is also an awesome glTF editor made by the same people that made the glTF viewer in the previous talk.&lt;/p&gt;&lt;h4&gt;Using multi-draw to speed up drawing many small objects&lt;/h4&gt;&lt;p&gt;Philip Taylor — Zea&lt;br&gt;&lt;a href="https://youtu.be/kZCqRlabZiU?t=3283"&gt;Timestamp: 54:40–1:12:20&lt;/a&gt;&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/Philip-Taylor---Leveraging-multi-draw-to-improve-performance.pdf"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/954/1*GwFtdaiJjoQNSPxk6GHTMw.png" /&gt;&lt;/figure&gt;&lt;p&gt;This talk was about using a new WebGL extension (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw"&gt;WEBGL_multi_draw&lt;/a&gt;) to efficiently draw millions of small objects, which are common for 3D design files.&lt;/p&gt;&lt;p&gt;Normally you might need to use many draw calls to render all these different objects because they have different textures/shaders/material properties. For these scenes where number of draw calls is the bottleneck, Philip described a technique to bind all data required ahead of time, and group these hundreds of thousands of draw calls into much fewer “multi draw” calls.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;“If instancing is drawing the same geometry many times, multi draw is drawing different geometries many times”&lt;/strong&gt; is how Philip described it. So it’s getting the same performance benefit of instancing with more flexibility.&lt;/li&gt;&lt;li&gt;He referenced this blog post as a good source to learn about it: &lt;a href="https://web.archive.org/web/20200703111311/http://www.openglsuperbible.com/2013/10/16/the-road-to-one-million-draws/"&gt;The road to 1 million draws&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;You essentially pack all your geometry into one huge vertex buffer&lt;/strong&gt; which you then pass to the multi-draw call with offsets that define geometry for separate objects&lt;/li&gt;&lt;li&gt;&lt;strong&gt;You have a “drawId”&lt;/strong&gt; which can be used in the shader to figure out which object is being drawn in the multi-draw call&lt;/li&gt;&lt;li&gt;&lt;strong&gt;It is not possible to switch/bind different uniforms&lt;/strong&gt; across different objects, since they are all grouped into one multi-draw call&lt;/li&gt;&lt;li&gt;&lt;strong&gt;So they bind everything into textures, including model matrices&lt;/strong&gt;. The drawId is used to index into these textures and get the model matrix, material properties, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The disadvantage of this is that all these properties have to be the same precision&lt;/strong&gt;, so this will be wasting extra memory. This is also a very non-trivial architecture, and makes it very difficult to change materials at runtime.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It was really cool to see at the end that there was a huge performance boost &lt;strong&gt;even when the multi-draw extension wasn’t supported.&lt;/strong&gt; The fallback is to issue individual draw calls, but not having to re-bind textures/uniforms between draw calls was a big boost. They showed a design model with 17k parts, 2.5 million triangles, 17k draw calls, running at 36 fps on an iPad in Safari&lt;/p&gt;&lt;h4&gt;Speeding up Unity’s WebGL export with batching techniques&lt;/h4&gt;&lt;p&gt;Brendan Duncan — Unity&lt;br&gt;&lt;a href="https://youtu.be/kZCqRlabZiU?t=4380"&gt;Timestamp: 1:13:00–1:30:11&lt;/a&gt;&lt;br&gt;&lt;a href="https://www.khronos.org/assets/uploads/developers/presentations/Brendan-Duncan---Unity-SRP-Batcher-For-WebGL.pdf"&gt;Slides&lt;/a&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D1fUUA80GICHAZvOG6IKRw.png" /&gt;&lt;/figure&gt;&lt;p&gt;Brendan shared how they were able to significantly speed up Unity’s WebGL export when drawing many different objects with unique materials. Normally you can only batch objects that share the same material/shader.&lt;/p&gt;&lt;p&gt;Brendan presented a technique to batch objects that have different materials by binding all data ahead of time and configuring each shader to use the right data (Unity calls this the “SRP Batcher”).&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;They initially couldn’t use this technique as-is in WebGL because it required 2 features not supported in WebGL&lt;/strong&gt;: &lt;a href="https://www.khronos.org/opengl/wiki/Uniform_(GLSL)/Explicit_Uniform_Location"&gt;uniform layout locations&lt;/a&gt; and &lt;a href="https://www.haroldserrano.com/blog/what-are-binding-points-in-opengl"&gt;buffer binding points&lt;/a&gt;. This is what allows the shaders to reference the right data when it is all sent to the GPU ahead of time.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Specifically the issue is that WebGL does not use integer uniform locations&lt;/strong&gt;. This is done as a security/sandboxing measure&lt;/li&gt;&lt;li&gt;&lt;strong&gt;They worked around this by creating an open source Emscripten plugin&lt;/strong&gt;: &lt;a href="https://github.com/emscripten-core/emscripten/pull/13887"&gt;https://github.com/emscripten-core/emscripten/pull/13887&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;This plugin preprocesses the shaders&lt;/strong&gt;. You can write OpenGL shaders using this feature (so they can keep the shaders as-is for Unity desktop/other platforms), the plugin will create a dictionary of all the uniform binding points, and generate GLSL code that works in WebGL with the correct bindings.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The result is a 2x improvement in the worst case scenario, for a scene with 1,600 objects, each with a different material, 4 real-time lights and 1 directional shadowmap.&lt;/p&gt;&lt;p&gt;I hope you found this useful! You can find me on Twitter (&lt;a href="https://twitter.com/Omar4ur"&gt;https://twitter.com/Omar4ur&lt;/a&gt;), I’d love to hear any thoughts.&lt;/p&gt;&lt;p&gt;You can sign up to be notified of the future WebGL/WebGPU meetups here: &lt;a href="https://www.khronos.org/news/subscribe/"&gt;https://www.khronos.org/news/subscribe/&lt;/a&gt;. You can also participate in the &lt;a href="https://groups.google.com/g/webgl-dev-list?pli=1"&gt;WebGL developers mailing list&lt;/a&gt; which is an active community of people sharing awesome projects, exchanging feedback, and asking questions.&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=8c27244e8b8f" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>Create a Complete Satellite Tracker from Scratch in JavaScript</title>
            <link>https://javascript.plainenglish.io/create-a-satellite-tracker-completely-in-javascript-9bc1ca61f6aa?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/9bc1ca61f6aa</guid>
            <category>programming</category>
            <category>coding</category>
            <category>geospatial</category>
            <category>software-development</category>
            <category>javascript</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Fri, 07 May 2021 23:18:46 GMT</pubDate>
            <ns1:updated>2021-05-10T07:38:44.734Z</ns1:updated>
            <description>&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QlzNP0jaa5iQ28d5X599lg.jpeg" /&gt;&lt;/figure&gt;&lt;p&gt;This tutorial will walk you through how to create a web app that visualizes the location of any satellite in real-time, like the International Space Station.&lt;/p&gt;&lt;p&gt;We’re going to do this from scratch, using the same techniques a real rocket scientist would!&lt;/p&gt;&lt;ol&gt;&lt;li&gt;We’ll look at where to get the data about individual satellites that the government publishes, known as &lt;strong&gt;Two-Line Element Sets&lt;/strong&gt;, or TLE’s.&lt;/li&gt;&lt;li&gt;We’ll use &lt;a href="https://github.com/shashwatak/satellite-js"&gt;satellite-js&lt;/a&gt; to predict the orbit of the satellite given the TLE’s (this is the rocket science part).&lt;/li&gt;&lt;li&gt;We’ll use &lt;a href="https://github.com/CesiumGS/cesium#readme"&gt;CesiumJS&lt;/a&gt; to visualize the result, but you can use any library/engine that can take in longitude, latitude, and height.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Below is a preview of the final result.&lt;/p&gt;&lt;iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fglitch.com%2Fembed%2F%23%21%2Fembed%2Fsatellite-viewer%3FpreviewSize%3D100&amp;amp;dntp=1&amp;amp;display_name=Glitch&amp;amp;url=https%3A%2F%2Fglitch.com%2Fembed%2F%23%21%2Fembed%2Fsatellite-viewer&amp;amp;image=https%3A%2F%2Fglitch.com%2Fedit%2Fimages%2Flogos%2Fglitch%2Fsocial-card%402x.png&amp;amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;amp;type=text%2Fhtml&amp;amp;schema=glitch" width="600" height="600" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/e20c405b6909206ed6143e22f997f3ae/href"&gt;https://medium.com/media/e20c405b6909206ed6143e22f997f3ae/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;This is showing the path of the International Space Station, sped up by 40x. To &lt;strong&gt;see its current location in real-time&lt;/strong&gt;, click the clock icon at the top-left of the clock wheel.&lt;/p&gt;&lt;p&gt;Here’s a &lt;a href="https://satellite-viewer.glitch.me/"&gt;direct link to the app&lt;/a&gt;. And the &lt;a href="https://glitch.com/edit/#!/satellite-viewer"&gt;source code on Glitch&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;1 — Get the satellite’s Two-Line Element Set&lt;/h3&gt;&lt;p&gt;A Two-Line Element Set, or TLE, is a data format that describes the motion of an object orbiting the Earth. It was created by the North American Aerospace Defense Command (NORAD). You can &lt;a href="https://celestrak.com/columns/v04n03/"&gt;read more about it and its history here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Given this description of the orbit, we can predict the location of where it’s going to be at any moment in time (which is step 2 below).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;This means that most “live” satellite trackers are not live in the same way that tracking a delivery car on a map is&lt;/strong&gt;. Instead of relying on constantly receiving position updates, those who track objects in space will often get the latest TLE’s (which are regularly updated) and use that to predict where the object is right now.&lt;/p&gt;&lt;p&gt;Where do we get the TLE’s? There is no one global official registry. Whoever owns the satellite and is monitoring it is responsible for updating and publishing the TLE for the benefit of the global space community (unless it’s a spy satellite).&lt;/p&gt;&lt;p&gt;We can find these TLE’s on &lt;a href="https://www.space-track.org"&gt;Space Track&lt;/a&gt; which is a registry run by the United States Space Command.&lt;/p&gt;&lt;p&gt;Another source is &lt;a href="https://celestrak.com/NORAD/elements/"&gt;this list on CeleStrak&lt;/a&gt; maintained by Dr. T.S. Kelso.&lt;/p&gt;&lt;p&gt;We’re going to use CeleStrak since it doesn’t require a login. To find the TLE for the International Space Station, click on the &lt;a href="https://celestrak.com/NORAD/elements/stations.txt"&gt;Space Stations&lt;/a&gt; link.&lt;/p&gt;&lt;p&gt;The first one is the TLE for the ISS:&lt;/p&gt;&lt;pre&gt;ISS (ZARYA)             &lt;br&gt;1 25544U 98067A   21122.75616700  .00027980  00000-0  51432-3 0  9994&lt;br&gt;2 25544  51.6442 207.4449 0002769 310.1189 193.6568 15.48993527281553&lt;/pre&gt;&lt;p&gt;The meaning of these numbers is &lt;a href="https://celestrak.com/columns/v04n03/#FAQ01"&gt;listed in table 1 in Dr T.S. Kelso’s column&lt;/a&gt;. Most of them are identifiers and metadata about the satellite, like when it was launched.&lt;/p&gt;&lt;p&gt;You can find TLE’s for weather satellites, GPS satellites, and even &lt;a href="https://celestrak.com/NORAD/elements/starlink.txt"&gt;SpaceX’s Starlink constellation&lt;/a&gt; in this same format.&lt;/p&gt;&lt;h3&gt;2 — Predict the satellite orbit&lt;/h3&gt;&lt;p&gt;Now that you know how to get the TLE of the object you’re interested in tracking, the next step is converting that to a position in time.&lt;/p&gt;&lt;p&gt;We’re going to use &lt;a href="https://github.com/shashwatak/satellite-js"&gt;satellite-js&lt;/a&gt; for this.&lt;/p&gt;&lt;p&gt;Include the library from a CDN:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/2f3a529b762b8a3c74cad54aa59887c8/href"&gt;https://medium.com/media/2f3a529b762b8a3c74cad54aa59887c8/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;Then pass the TLE to it, and a time:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/6137569e24d81eb2e9f665298974666c/href"&gt;https://medium.com/media/6137569e24d81eb2e9f665298974666c/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;Now we have the position of the satellite at the current time, new Date().&lt;/p&gt;&lt;p&gt;This position is produced as a result of simulating a specific model of satellite motion. This model is called SGP4/SDP4. All TLE’s assume this specific model.&lt;/p&gt;&lt;p&gt;If you’re wondering about the accuracy of this model, the short answer is, &lt;a href="https://celestrak.com/columns/v04n05/#FAQ06"&gt;it depends&lt;/a&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;em&gt;Accuracy of the two-line element sets is dependent upon a number of factors. These range from the particular sensors used and amount of data collected to the type of orbit and condition of the space environment. Unfortunately, since these factors vary for each element set, so does the accuracy. While NORAD has experimented with methods to incorporate prediction quality into the element sets, none of these methods has yet proved successful.&lt;/em&gt;&lt;/blockquote&gt;&lt;h3&gt;3 — Visualize the result&lt;/h3&gt;&lt;p&gt;Now we have a way to get the location of any satellite, at any given time. We can pass in future times to animate its path, which we’ll do in the next step.&lt;/p&gt;&lt;p&gt;First, let’s see how to visualize an individual point in space using CesiumJS.&lt;/p&gt;&lt;p&gt;We load the library from CDN:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/2c4527c4f2254a0d37061e3aa6a6768b/href"&gt;https://medium.com/media/2c4527c4f2254a0d37061e3aa6a6768b/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;And create a container element:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/782d07c40cad14b786795f6efc04d71c/href"&gt;https://medium.com/media/782d07c40cad14b786795f6efc04d71c/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;We then initialize the viewer. Here we pass in some extra options to disable functionality that requires an access token:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/cda9f9e7cc1501ff02506e415487592c/href"&gt;https://medium.com/media/cda9f9e7cc1501ff02506e415487592c/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;Finally, we’ll visualize the satellite position as a red dot in space:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/7007a794ecca7681ef6c12850ae59a97/href"&gt;https://medium.com/media/7007a794ecca7681ef6c12850ae59a97/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;See the &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=simple.html"&gt;complete source code of this step in simple.html on Glitch&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;4 — Animate the path&lt;/h3&gt;&lt;p&gt;To animate the path, we just need to sample more positions in the future. CesiumJS has a built-in way to interpolate between these samples over time.&lt;/p&gt;&lt;p&gt;The setup for this is a bit verbose. &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=index.html%3A6%3A82"&gt;You can see the full code on Glitch&lt;/a&gt;. The important concepts are described below.&lt;/p&gt;&lt;p&gt;We create a SampledPositionProperty. This is an object that will hold position samples over time and will interpolate between them:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/13e0156e2dcc1737fa77ac138e4b2ed7/href"&gt;https://medium.com/media/13e0156e2dcc1737fa77ac138e4b2ed7/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;We loop through however many samples we want to get, and for each sample, we construct a time object, called JulianDate in CesiumJS, and a position, and we add that as a sample:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/2332306ab023506f652dbb7477218fc5/href"&gt;https://medium.com/media/2332306ab023506f652dbb7477218fc5/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;Finally, we pass this positionsOverTime object to our point.&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/40b50d89de948e96f6398ed710ed1cf5/href"&gt;https://medium.com/media/40b50d89de948e96f6398ed710ed1cf5/href&lt;/a&gt;&lt;/iframe&gt;&lt;p&gt;The point will move as the timeline at the bottom moves. To attach the camera to the moving point we do:&lt;/p&gt;&lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&gt;&lt;a href="https://medium.com/media/9f1c4f9a46376bb13b2b9944daf4d3a5/href"&gt;https://medium.com/media/9f1c4f9a46376bb13b2b9944daf4d3a5/href&lt;/a&gt;&lt;/iframe&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;I hope you enjoyed learning a little bit about what goes into building a satellite tracker. There’s a lot more to the topic we didn’t touch on, like what exactly do the parameters in the TLE mean? How often are they updated? How are they updated?&lt;/p&gt;&lt;p&gt;I don’t know, but I find it really empowering to know what formats this kind of data is published in &amp;amp; where to get it, and quite amazing that we can do all this directly in the browser with JavaScript!&lt;/p&gt;&lt;p&gt;Here are a couple of fun ideas to explore now that we can do this:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Visualize multiple satellites&lt;/strong&gt;, like the entire Starlink constellation. Inspired by &lt;a href="https://celestrak.com/cesium/orbit-viz.php?tle=/pub/TLE/catalog.txt&amp;amp;satcat=/pub/satcat.txt&amp;amp;referenceFrame=1"&gt;Celestrak’s viewer&lt;/a&gt; which shows every satellite in its catalog. Perhaps visualize how the number of Starlink satellites grew over time?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Or simulate what it would look like from street level&lt;/strong&gt;. Maybe add buildings/elevation data to find the best place in the city to see the satellite?&lt;/p&gt;&lt;p&gt;There’s a prototype of this in &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=street-level.html%3A1%3A0"&gt;street-level.html&lt;/a&gt; in the Glitch source code. Demo: &lt;a href="https://satellite-viewer.glitch.me/street-level.html"&gt;https://satellite-viewer.glitch.me/street-level.html&lt;/a&gt;.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/600/1*Hn4rzImReFMIlObMbLwjoQ.gif" /&gt;&lt;/figure&gt;&lt;p&gt;See also &lt;a href="https://james.darpinian.com/satellites/"&gt;James Darpinian’s “See a satellite tonight”&lt;/a&gt; app which uses a combination of CesiumJS and Google street view.&lt;/p&gt;&lt;p&gt;It might also be fun to use a 3D model of the right scale instead of a dot, and get a real sense of how close satellites get to each other in space.&lt;/p&gt;&lt;p&gt;Thanks for reading! If you found this helpful, follow me on &lt;a href="https://twitter.com/Omar4ur"&gt;Twitter @Omar4ur&lt;/a&gt; to see more of my work. Otherwise, you can also find me &lt;a href="https://omarshehata.me/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;More content at &lt;/em&gt;&lt;a href="http://plainenglish.io/"&gt;&lt;em&gt;plainenglish.io&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=9bc1ca61f6aa" width="1" height="1" alt=""&gt;&lt;hr&gt;&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/create-a-satellite-tracker-completely-in-javascript-9bc1ca61f6aa"&gt;Create a Complete Satellite Tracker from Scratch in JavaScript&lt;/a&gt; was originally published in &lt;a href="https://javascript.plainenglish.io"&gt;JavaScript in Plain English&lt;/a&gt; on Medium, where people are continuing the conversation by highlighting and responding to this story.&lt;/p&gt;</description>
        </item><item>
            <title>How to Load Sketchfab Models Directly in a Three.js App</title>
            <link>https://javascript.plainenglish.io/how-to-load-sketchfab-models-directly-in-a-threejs-app-f4e76bacf5e6?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f4e76bacf5e6</guid>
            <category>web-development</category>
            <category>coding</category>
            <category>javascript</category>
            <category>software-development</category>
            <category>programming</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Tue, 27 Apr 2021 23:55:16 GMT</pubDate>
            <ns1:updated>2021-05-05T06:42:59.933Z</ns1:updated>
            <description>&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/0*oKK011iDTWzu83bF" /&gt;&lt;figcaption&gt;Photo by &lt;a href="https://unsplash.com/@cgower?utm_source=medium&amp;amp;utm_medium=referral"&gt;Christopher Gower&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Sketchfab’s API gives you programmatic access to the largest collection of glTF 3D models on the web. This article walks you through a minimal code example to show you how to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Let your users authenticate with the Sketchfab API&lt;/li&gt;&lt;li&gt;Download a 3D model as a zip file containing the glTF&lt;/li&gt;&lt;li&gt;Load this zip file into Three.js&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example"&gt;OmarShehata/threejs-sketchfab-example&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;How it works&lt;/h4&gt;&lt;p&gt;I originally implemented this to let readers of my &lt;a href="https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9"&gt;WebGL outlines tutorial&lt;/a&gt; see how the effect looked on test cases of their choosing since I kept finding algorithms that didn’t work on my specific corner cases (but I wouldn’t find out until after I implemented it/downloaded and ran it).&lt;/p&gt;&lt;p&gt;It’s a really easy way to let users bring in their own data (or millions of example models).&lt;/p&gt;&lt;p&gt;You can see how this works in this outlines live demo:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open the demo: &lt;a href="https://omarshehata.github.io/csb-l01dp/"&gt;https://omarshehata.github.io/csb-l01dp/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;Login to Sketchfab&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;When directed back to the app, paste a link of a model in the&lt;strong&gt; Sketchfab URL field&lt;/strong&gt;, like this: &lt;a href="https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393"&gt;https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The model must be downloadable by the Sketchfab account that’s logged in.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/600/1*xZcYU7BtVl-CDfklPWxS1Q.gif" /&gt;&lt;figcaption&gt;&lt;a href="https://omarshehata.github.io/csb-l01dp/"&gt;The demo app&lt;/a&gt; loads a 3D model directly from any Sketchfab URL into a ThreeJS scene&lt;/figcaption&gt;&lt;/figure&gt;&lt;h4&gt;1 — Authenticate with the Sketchfab API&lt;/h4&gt;&lt;p&gt;The first step is to register your app with Sketchfab. The instructions for this are here:&lt;/p&gt;&lt;p&gt;&lt;a href="https://sketchfab.com/developers/oauth#registering-your-app"&gt;OAuth Login - Developers&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The current process at the time of writing is to contact them.&lt;/p&gt;&lt;p&gt;You’ll need to pick a &lt;strong&gt;redirect URI&lt;/strong&gt;. This should be the final URI where you will deploy your app.&lt;/p&gt;&lt;p&gt;You’ll want to use the &lt;strong&gt;Implicit &lt;/strong&gt;grant type. We can’t keep an API key a secret in a web app, so we instead rely on the redirect URI (if someone malicious uses your client ID, Sketchfab will redirect them to your real app after login, regardless of who may have initiated the login).&lt;/p&gt;&lt;p&gt;After your register your app you’ll have a &lt;strong&gt;Client ID&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;You’ll use this to send the user to Sketchfab for login as shown here:&lt;/p&gt;&lt;pre&gt;const CLIENT_ID = &amp;#39;YOUR_CLIENT_ID_HERE&amp;#39;;&lt;br&gt;const AUTHENTICATION_URL = `https://sketchfab.com/oauth2/authorize/?state=123456789&amp;amp;response_type=token&amp;amp;client_id=${CLIENT_ID}`;&lt;br&gt;window.open(AUTHENTICATION_URL, &amp;#39;_blank&amp;#39;);&lt;/pre&gt;&lt;p&gt;Once the login is done, you’ll need to &lt;strong&gt;grab the access token from the URL&lt;/strong&gt;. You can find a code snippet in the source code that does this and stores it in local storage here:&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L77-L92"&gt;https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L77-L92&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You’ll use this token for subsequent API calls.&lt;/p&gt;&lt;h4&gt;2 — Download the 3D model&lt;/h4&gt;&lt;p&gt;Once you have a token, you can use this to fetch a download URI for the glTF model.&lt;/p&gt;&lt;p&gt;Here is the code snippet for fetching the download URI given any Sketchfab URI like this: &lt;a href="https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393"&gt;https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L95-L115"&gt;https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L95-L115&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Note that this request will fail if the user who is logged in does not have access to download this model. This will be true for store models that require a purchase, or free models that are not downloadable.&lt;/p&gt;&lt;p&gt;You can filter for downloadable models in the Sketchfab search:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/980/1*uXOMlDYt9xcyBzvWVQq9fA.png" /&gt;&lt;/figure&gt;&lt;p&gt;This will show you either free models you can download or models that can be purchased.&lt;/p&gt;&lt;p&gt;Now that we have a URL to a zip file containing a glTF model, we can pass that to ThreeJS to load it.&lt;/p&gt;&lt;h4&gt;3 — Load the ZIP file into ThreeJS&lt;/h4&gt;&lt;p&gt;This was the tricky part of me. Normally ThreeJS requires a direct URL to the glTF file. To load it from a zip file we’re going to (1) unzip the contents into memory using JSZip.&lt;/p&gt;&lt;p&gt;We can’t just pass the unzipped raw content to ThreeJS, because a glTF file may reference other files by a filepath (image or geometry resources). So we need to (2) create a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob"&gt;Blob&lt;/a&gt; for each resource and (3) override the resources the glTF file is requesting with the Blob URI’s.&lt;/p&gt;&lt;p&gt;For example, if the glTF file is trying to load “textures/defaultMat_baseColor.jpeg” as a relative filepath, we detect this, and instead pass this URI:&lt;/p&gt;&lt;pre&gt;//Unzip from JSZip&lt;br&gt;const file = unzippedBaseColorJPEGFile;&lt;br&gt;// Create a Blob from this file&lt;br&gt;const blob = await file.async(&amp;#39;blob&amp;#39;);&lt;br&gt;// Create a URL to this Blob&lt;br&gt;const baseColorBlobUrl = URL.createObjectURL(blob);&lt;br&gt;// Use ThreeJS&amp;#39;s loading manager so instead of loading from relative filepaths we load from the blob URI&amp;#39;s we created&lt;/pre&gt;&lt;pre&gt;const loadingManager = new THREE.LoadingManager();                            loadingManager.setURLModifier((url) =&amp;gt; {&lt;/pre&gt;&lt;pre&gt;  if (url == &amp;#39;textures/defaultMat_baseColor.jpeg&amp;#39;) {&lt;br&gt;    return baseColorBlobUrl;&lt;br&gt;  }&lt;/pre&gt;&lt;pre&gt;});&lt;/pre&gt;&lt;p&gt;We use &lt;a href="https://threejs.org/docs/#api/en/loaders/managers/LoadingManager"&gt;ThreeJS’s LoadingManager&lt;/a&gt; to do this.&lt;/p&gt;&lt;p&gt;Here is the code snippet that can take a URL to any zipped glTF and load it in ThreeJS:&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L30-L70"&gt;https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L30-L70&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;4 — Display attribution&lt;/h4&gt;&lt;p&gt;Using 3D models from Sketchfab in your application requires that you display attribution to the original author. &lt;a href="https://help.sketchfab.com/hc/en-us/articles/360038413232-Crediting-users-for-3D-model-downloads"&gt;Read more about this on Sketchfab&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;We can automatically get the attribution &amp;amp; license information from this &lt;a href="https://docs.sketchfab.com/data-api/v3/index.html#!/models/get_v3_models_uid"&gt;Data API route&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Here is a function that will construct the attribution text given a modelID:&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/8d126d00faf47fb0b99f9f2f7c78a25332ccfb7b/SketchfabIntegration.js#L121-L142"&gt;https://github.com/OmarShehata/threejs-sketchfab-example/blob/8d126d00faf47fb0b99f9f2f7c78a25332ccfb7b/SketchfabIntegration.js#L121-L142&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The example app will display the attribution in the bottom left corner, linking to the original model URL, author’s Sketchfab profile, and the license.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Wy2-coSbTSgxSipDT_0ZQQ.png" /&gt;&lt;/figure&gt;&lt;h4&gt;Known issues&lt;/h4&gt;&lt;p&gt;One problem with loading some Sketchfab models is that their scale will be much bigger than the current viewport. Another problem is some models may not be centered around the origin, so they may not be visible when loaded.&lt;/p&gt;&lt;p&gt;Normalizing and scaling models when loading them in ThreeJS would help solve this, similar to how &lt;a href="https://gltf-viewer.donmccurdy.com/"&gt;Don McCurdy’s glTF Viewer&lt;/a&gt; works.&lt;/p&gt;&lt;p&gt;Thanks for reading! If you found this helpful, follow me on &lt;a href="https://twitter.com/Omar4ur"&gt;Twitter @Omar4ur&lt;/a&gt; to see more of my work. Otherwise, you can also find me &lt;a href="https://omarshehata.me/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://plainenglish.io/"&gt;&lt;em&gt;More content at plainenglish.io&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=f4e76bacf5e6" width="1" height="1" alt=""&gt;&lt;hr&gt;&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/how-to-load-sketchfab-models-directly-in-a-threejs-app-f4e76bacf5e6"&gt;How to Load Sketchfab Models Directly in a Three.js App&lt;/a&gt; was originally published in &lt;a href="https://javascript.plainenglish.io"&gt;JavaScript in Plain English&lt;/a&gt; on Medium, where people are continuing the conversation by highlighting and responding to this story.&lt;/p&gt;</description>
        </item><item>
            <title>How to render outlines in WebGL</title>
            <link>https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8253c14724f9</guid>
            <category>webgl</category>
            <category>programming</category>
            <category>shaders</category>
            <category>javascript</category>
            <category>graphics-programming</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Mon, 18 Jan 2021 21:25:17 GMT</pubDate>
            <ns1:updated>2022-11-10T18:40:54.968Z</ns1:updated>
            <description>&lt;p&gt;This article describes how to visualize outlines for a WebGL scene as a post process, with example &lt;a href="https://github.com/OmarShehata/webgl-outlines"&gt;implementations for ThreeJS &amp;amp; PlayCanvas&lt;/a&gt;.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/818/1*iqlf3PpSUFIZgbyO3hap6w.png" /&gt;&lt;figcaption&gt;Left — boundary outline only. Right — the technique described in this article. Boat model by &lt;a href="https://poly.google.com/view/84-DYhLzxNq"&gt;Google Poly&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Note: I’ve written a follow up that builds on this article with an improved technique that solves many of the artifacts present here. See &lt;/strong&gt;&lt;a href="https://omar-shehata.medium.com/better-outline-rendering-using-surface-ids-with-webgl-e13cdab1fd94"&gt;&lt;strong&gt;Better outline rendering using surface IDs with WebGL&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are a few common approaches that produce boundary-only outlines as shown on the left of the above picture.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Drawing objects twice, such that the backfaces make up the outline, &lt;a href="https://medium.com/@joshmarinacci/cartoon-outline-effect-6c4e95545537"&gt;described here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;A post process using the depth buffer, &lt;a href="https://threejs.org/examples/webgl_postprocessing_outline.html"&gt;implemented in ThreeJS here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Similar post process &lt;a href="https://playcanvas.github.io/#graphics/model-outline.html"&gt;implemented in PlayCanvas here&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Rendering the full outlines of a scene is particularly useful when you need to clearly see the geometry and structure of your scene. For example, the stylized aesthetic of &lt;a href="https://obradinn.com/"&gt;Return of the Obra Dinn&lt;/a&gt; would be very hard to navigate without clear outlines.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ORbwUBx1jHY_xZysA7CpMw.jpeg" /&gt;&lt;figcaption&gt;Top, a stylized two-tone lighting in ThreeJS inspired by Return of the Obra Dinn. Bottom, the same scene with outlines. Ship model from &lt;a href="https://sketchfab.com/3d-models/russian-archipelago-frigate-svjatoi-nikolai-3e89828a09fa4a7e840a4ab3ce5482e2"&gt;Museovirasto Museiverket Finnish Heritage Agency on Sketchfab&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The technique I describe here is similar to the post process shaders linked above, with the addition of a “normal buffer” in the outline pass that is used to find those inner edges.&lt;/p&gt;&lt;h3&gt;Live Demo&lt;/h3&gt;&lt;p&gt;Below is a link to a live demo of this technique implemented in ThreeJS. You can drag and drop any glTF model (as a single .glb/glTF file) to see the outline effect on your own test models:&lt;/p&gt;&lt;p&gt;&lt;a href="https://threejs-outlines-postprocess.glitch.me/"&gt;https://threejs-outlines-postprocess.glitch.me/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You can also find the source code on GitHub: &lt;a href="https://github.com/OmarShehata/webgl-outlines"&gt;https://github.com/OmarShehata/webgl-outlines&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Overview of the technique&lt;/h3&gt;&lt;p&gt;Our outline shader needs 3 inputs:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The depth buffer&lt;/li&gt;&lt;li&gt;The normal buffer&lt;/li&gt;&lt;li&gt;The color buffer (the original scene)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Given these 3 inputs we will compute the difference between the current pixel’s depth value and its neighbors.&lt;strong&gt; A large depth difference&lt;/strong&gt; tells us there’s a distance gap (this will typically give you the outer boundary of an object but not fine details on its surface).&lt;/p&gt;&lt;p&gt;We will do the same with the normal buffer. &lt;strong&gt;A difference in normal direction&lt;/strong&gt; means a sharp corner. This is what gives us the finer details.&lt;/p&gt;&lt;p&gt;We then combine those differences to form the final outline, and combine that with the color buffer to add the outlines to the scene.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Tip: The live demo has a scaling factor for each of the normal &amp;amp; depth. You can scale that to 0 to see the influence of each on the final set of outlines.&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Overview of the rendering pipeline&lt;/h3&gt;&lt;p&gt;Here is how we’re going to set up our effect:&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/901/1*gnFxDuZxaa2-zr9vgT8qjg.png" /&gt;&lt;figcaption&gt;This effect requires 3 passes. Two render-passes and one post-process.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Render pass 1&lt;/strong&gt; captures the color of all objects in the scene in “Scene Buffer”.&lt;br&gt;It also outputs the depth of every pixel in a separate “Depth Buffer”.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Render pass 2&lt;/strong&gt; re-renders all objects in the scene with a normal material that colors it using the object’s view-normal at every pixel. This is written&lt;br&gt;to the “Normal Buffer”.&lt;/p&gt;&lt;p&gt;Finally, &lt;strong&gt;Outline pass&lt;/strong&gt; is a post process, taking the 3 buffers and rendering onto a fullscreen quad.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yzvNhrtSM4IAEZs_VOf2_g.png" /&gt;&lt;figcaption&gt;Each stage in this rendering pipeline visualized.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This can be further optimized by modifying the engine to combine the normal and depth buffers into one “NormalDepth”, &lt;a href="https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html"&gt;similar to how Unity does it&lt;/a&gt;, to avoid the need for the 2nd render pass.&lt;/p&gt;&lt;p&gt;A final step not shown in the diagram is an &lt;strong&gt;FXAA pass&lt;/strong&gt;, which we need because we’re rendering the scene onto an off-screen buffer, which disables the browser’s native antialiasing.&lt;/p&gt;&lt;h3&gt;Implementation&lt;/h3&gt;&lt;p&gt;It’s difficult to describe this technique without reference to a specific engine since a core part of it is how to set up the rendering pipeline described above. The implementation details here will be specific to ThreeJS but you can see the PlayCanvas source code along with an editor project here:&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/webgl-outlines/tree/main/playcanvas"&gt;https://github.com/OmarShehata/webgl-outlines/tree/main/playcanvas&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;1. Get the depth buffer&lt;/h4&gt;&lt;p&gt;3D engines will typically draw all opaque objects into a depth buffer to ensure objects are rendered correctly without having to sort them back to front. All we have to do is get a reference to this buffer to pass it to our outline post process.&lt;/p&gt;&lt;p&gt;In ThreeJS, this means setting depthBuffer = true on the render target we’re creating so that we capture the “scene color” and the “depth buffer” at the same time. See: &lt;a href="https://threejs.org/docs/#api/en/renderers/WebGLRenderTarget.depthBuffer"&gt;https://threejs.org/docs/#api/en/renderers/WebGLRenderTarget.depthBuffer&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In our demo this is created here:&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/4d94f360e083540c8bb860bed3509c0d4528d22c/threejs/src/index.js#L31-L42"&gt;https://github.com/OmarShehata/webgl-outlines/blob/4d94f360e083540c8bb860bed3509c0d4528d22c/threejs/src/index.js#L31-L42&lt;/a&gt;&lt;/p&gt;&lt;p&gt;There are a few caveats to know when working with the depth buffer:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You need to know how the values are “packed”. Given the limited precision, does the engine just linearly interpolate Z values camera.near to camera.far? Does it do this in reverse? Or use a logarithmic depth buffer?&lt;/li&gt;&lt;li&gt;The engine most likely already has some mechanisms for working with depth values that you can re-use. For ThreeJS, you can include #include &amp;lt;packing&amp;gt; in your fragment shader which will allow you to &lt;a href="https://github.com/mrdoob/three.js/blob/66b9fa344ce01581033d171e1de09dd86bd5a3d7/src/renderers/shaders/ShaderChunk/packing.glsl.js"&gt;use these helper functions&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;For just visualizing it for debug purposes, you can collapse your camera’s near/far to cover the bounds of the object so you can more clearly see the image.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;2. Create a normal buffer&lt;/h4&gt;&lt;p&gt;If your engine supports outputting the normals of everything in the scene, you should use that directly. Otherwise, you’ll need to create a second render pass. This needs to be identical to the original render, with the only exception that all materials on all meshes are replaced by a “normal material” that renders the view space normals.&lt;/p&gt;&lt;p&gt;ThreeJS has a convenient &lt;a href="https://threejs.org/docs/#api/en/scenes/Scene.overrideMaterial"&gt;scene.overrideMaterial&lt;/a&gt; method we can use for exactly this purpose. Instead of creating a new identical scene and a new identical camera, we can directly re-render the same scene with the given override material.&lt;/p&gt;&lt;pre&gt;this.renderScene.overrideMaterial = new THREE.MeshNormalMaterial();&lt;/pre&gt;&lt;pre&gt;renderer.render(this.renderScene, this.renderCamera);                      &lt;/pre&gt;&lt;pre&gt;this.renderScene.overrideMaterial = null;&lt;/pre&gt;&lt;p&gt;In our ThreeJS implementation &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/4d94f360e083540c8bb860bed3509c0d4528d22c/threejs/src/CustomOutlinePass.js#L60"&gt;this is encapsulated in CustomOutlinePass.js&lt;/a&gt; for convenience, but it is a completely separate render pass.&lt;/p&gt;&lt;h4&gt;3. Create the outline post process&lt;/h4&gt;&lt;p&gt;The outline effect is a post process — we’ve already rendered the scene, now we need to take those buffers, combine them, and render the result onto a fullscreen quad. The result of that will either go directly to the screen or to the next pass in the pipeline (like FXAA).&lt;/p&gt;&lt;p&gt;We need to pass 3 uniforms: sceneBuffer, depthBuffer, and normalBuffer.&lt;/p&gt;&lt;p&gt;We create helper functions to read the depth at an offset from a given pixel. Then we sum up the difference between the current pixel’s depth value and its neighbors.&lt;/p&gt;&lt;pre&gt;float depth = getPixelDepth(0, 0);                           &lt;br&gt;// Difference between depth of neighboring pixels and current.                           &lt;br&gt;float depthDiff = 0.0;                           &lt;br&gt;depthDiff += abs(depth - getPixelDepth(1, 0));                           depthDiff += abs(depth - getPixelDepth(-1, 0));                           depthDiff += abs(depth - getPixelDepth(0, 1));                           depthDiff += abs(depth - getPixelDepth(0, -1));&lt;/pre&gt;&lt;p&gt;The same thing is done for normals as well. Since the normal is a 3 dimensional vector, we get the difference using the distance function.&lt;/p&gt;&lt;pre&gt;vec3 normal = getPixelNormal(0, 0);&lt;br&gt;// Difference between normals of neighboring pixels and current                           float normalDiff = 0.0;                           &lt;br&gt;normalDiff += distance(normal, getPixelNormal(1, 0));                           normalDiff += distance(normal, getPixelNormal(0, 1));                           normalDiff += distance(normal, getPixelNormal(0, 1));                           normalDiff += distance(normal, getPixelNormal(0, -1));&lt;/pre&gt;&lt;p&gt;To render the outline only at this point we would do:&lt;/p&gt;&lt;pre&gt;float outline = normalDiff + depthDiff;&lt;br&gt;gl_FragColor = vec4(vec3(outline), 1.0);&lt;/pre&gt;&lt;p&gt;There’s a few parameters here to tweak:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;We can include the diagonals in our neighbor sampling to get a more accurate outline&lt;/li&gt;&lt;li&gt;We can sample one or more neighbors further, to get thicker outlines&lt;/li&gt;&lt;li&gt;We can multiply normalDiff and depthDiff by a scalar to control their influence on the final outline&lt;/li&gt;&lt;li&gt;We can tweak normalDiff and depthDiff so that only really stark differences in depth or normal direction show up as an outline. This is what the “normal bias” and the “depth bias” parameters control.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is implemented in &lt;a href="https://github.com/OmarShehata/webgl-outlines/blob/cf81030d6f2bc20e6113fbf6cfd29170064dce48/threejs/src/CustomOutlinePass.js#L144"&gt;CustomOutlinePass.js&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;4. Combine the outlines with your final scene&lt;/h4&gt;&lt;p&gt;Finally, to combine the outline onto the scene, we mix the scene color with a chosen “outline color”, based on our outline value.&lt;/p&gt;&lt;pre&gt;float outline = normalDiff + depthDiff;&lt;br&gt;vec4 outlineColor = vec4(1.0, 1.0, 1.0, 1.0);//white outline&lt;br&gt;gl_FragColor = vec4(mix(sceneColor, outlineColor, outline));&lt;/pre&gt;&lt;p&gt;This is also where you can create any custom logic for how you combine your outline with your scene.&lt;/p&gt;&lt;p&gt;For example, in the &lt;em&gt;Return of the Obra Dinn&lt;/em&gt;, the outlines change color based on the lighting. To achieve this effect we would check the lighting direction against the surface normal in our normal buffer, and color the outline white if it not in direct light, and black if it is facing the light source(s).&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/815/1*Di1cDB21IXs0Og6lfli8PA.png" /&gt;&lt;figcaption&gt;Stylized lighting in ThreeJS inspired by Return of the Obra Dinn. Notice that the outlines change color based on the scene’s lighting.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Thanks for reading! If you found this helpful, &lt;a href="https://omarshehata.me/notebook/my_newsletter"&gt;sign up to my newsletter&lt;/a&gt; to follow my work &amp;amp; stay in touch.&lt;/p&gt;&lt;p&gt;Thanks to Ronja Böhringer whose &lt;a href="https://www.ronja-tutorials.com/2018/07/15/postprocessing-outlines.html"&gt;Outlines via Postprocessing&lt;/a&gt; article helped me understand this technique and adapt it for the web.&lt;/p&gt;&lt;p&gt;If you have any suggestions or corrections to the code or technique, open an issue on GitHub (&lt;a href="https://github.com/OmarShehata/webgl-outlines/"&gt;https://github.com/OmarShehata/webgl-outlines/&lt;/a&gt;) or reach out to me directly. You can find my contact info at: &lt;a href="https://omarshehata.me/"&gt;https://omarshehata.me/&lt;/a&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=8253c14724f9" width="1" height="1" alt=""&gt;</description>
        </item><item>
            <title>How to Fix Gimbal Lock in N-Dimensions</title>
            <link>https://omar-shehata.medium.com/how-to-fix-gimbal-lock-in-n-dimensions-f2f7baec2b5e?source=rss-49201ddae41c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f2f7baec2b5e</guid>
            <category>geometric-algebra</category>
            <category>fourth-dimension</category>
            <category>gimbal-lock</category>
            <category>rotation</category>
            <dc:creator>Omar Shehata</dc:creator>
            <pubDate>Sun, 23 Aug 2020 04:12:11 GMT</pubDate>
            <ns1:updated>2020-08-24T18:06:18.090Z</ns1:updated>
            <description>&lt;p&gt;Gimbal lock is a common issue that arises in 3D rotation systems. Conventional wisdom says that you should represent your rotations as quaternions to avoid this problem (as stated in many popular &lt;a href="https://docs.unity3d.com/ScriptReference/Quaternion.html"&gt;game engine docs &lt;/a&gt;and countless &lt;a href="https://www.youtube.com/watch?v=N5PDboNJwks"&gt;YouTube videos&lt;/a&gt;). But I couldn’t find any good explanations of exactly &lt;em&gt;how&lt;/em&gt; quaternions solve it.&lt;/p&gt;&lt;p&gt;This was important for me because I was implementing a 4D geometry viewer and spent a lot of time trying to figure out how to generalize quaternions to higher dimensions, only to discover that you can still get gimbal lock with quaternions!&lt;/p&gt;&lt;p&gt;The answer is it’s not about what you use to represent your rotations (quaternions, matrices, or rotors), it’s about how you apply those rotations.&lt;/p&gt;&lt;h3&gt;What causes gimbal lock?&lt;/h3&gt;&lt;p&gt;Gimbal lock is the loss of a degree of freedom in a rotation system. It will always happen in any system that uses &lt;strong&gt;Euler angles&lt;/strong&gt;, where you rotate your object by applying a fixed set of successive rotations.&lt;/p&gt;&lt;p&gt;In 3D, this happens when one of the 3 axes of rotation becomes parallel to any other one (or in other words, when the “gimbals” line up). This is shown in the animation below. It starts with the +Z side facing the camera. The first 90 degree rotation places the top cube in a gimbal locked state: rotating by the blue and red gimbals now produce the same rotation. It is not possible in this state to rotate around the cube’s local X axis (pointing towards the camera). This is the degree of freedom we’ve lost and is represented by the red gimbal in the bottom view.&lt;/p&gt;&lt;figure&gt;&lt;img alt="" src="https://cdn-images-1.medium.com/max/800/1*ZeNkiwy9cx0N_t3ceVOD5w.gif" /&gt;&lt;/figure&gt;&lt;p&gt;It’s easier to see this by trying it yourself in this demo (requires a keyboard):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Rotate the cubes with W,A,S,D and Q, E&lt;/li&gt;&lt;li&gt;R to reset&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://gimbal-lock-quaternions.glitch.me/"&gt;https://gimbal-lock-quaternions.glitch.me/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The top two cubes use Euler angles, so there will always be a way to get into this gimbal locked state. All you have to do is line up the blue and red gimbals. Then compare the behavior with the bottom two cubes, which show what the correct rotation should be.&lt;/p&gt;&lt;p&gt;Here is pseudocode for how the rotation for the top left cube is implemented:&lt;/p&gt;&lt;pre&gt;rotationAroundX = Matrix3.fromAxisAngle(angle1, Xaxis);&lt;br&gt;rotationAroundY = Matrix3.fromAxisAngle(angle2, Yaxis);&lt;br&gt;rotationAroundZ = Matrix3.fromAxisAngle(angle3, Zaxis);&lt;/pre&gt;&lt;pre&gt;cubeRotation = rotationAroundX * rotationAroundY * rotationAroundZ;&lt;/pre&gt;&lt;p&gt;This is an Euler angle system that uses rotation matrices to represent and apply the rotations. We will get exactly the same behavior if we swap out the matrices for quaternions.&lt;/p&gt;&lt;p&gt;Here is how the top right cube is implemented:&lt;/p&gt;&lt;pre&gt;rotationAroundX = Quaternion.fromAxisAngle(angle1, Xaxis);&lt;br&gt;rotationAroundY = Quaternion.fromAxisAngle(angle2, Yaxis);&lt;br&gt;rotationAroundZ = Quaternion.fromAxisAngle(angle3, Zaxis);&lt;/pre&gt;&lt;pre&gt;cubeRotation = rotationAroundX * rotationAroundY * rotationAroundZ;&lt;/pre&gt;&lt;p&gt;This is an Euler angle system that uses quaternions to represent and apply the rotations, and thus also suffers from gimbal lock.&lt;/p&gt;&lt;h3&gt;How do you fix gimbal lock?&lt;/h3&gt;&lt;p&gt;To fix gimbal lock, we must avoid modelling this physical gimbal system.&lt;/p&gt;&lt;p&gt;In 3D, instead of using 3 fixed angles that we multiply together to get the final rotation, we will:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Construct a quaternion that describes a rotation around whatever axis we want, and the angle to rotate by.&lt;/li&gt;&lt;li&gt;Multiply that by the object’s current rotation as represented by a quaternion.&lt;/li&gt;&lt;li&gt;Take the result and overwrite it back into the object’s current stored rotation.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This is how the bottom right cube in the demo above is implemented. The pseudocode looks like this:&lt;/p&gt;&lt;pre&gt;// We want to rotate by 0.05 radians in this frame.&lt;br&gt;rotationThisFrame = Quaternion.fromAxisAngle(0.05, arbitraryAxis);&lt;/pre&gt;&lt;pre&gt;cubeRotation = cubeRotation * rotationThisFrame;&lt;/pre&gt;&lt;p&gt;Nothing about this technique is unique to quaternions. Here is how the bottom left cube implements this with matrices:&lt;/p&gt;&lt;pre&gt;rotationThisFrame = Matrix3.fromAxisAngle(0.05, arbitraryAxis);&lt;/pre&gt;&lt;pre&gt;cubeRotation = cubeRotation * rotationThisFrame;&lt;/pre&gt;&lt;p&gt;The “arbitrary axis” is the cube’s local X/Y/Z axes, depending on what key is pressed. It can instead be the global X/Y/Z axes if we wanted to rotate relative to a fixed global frame.&lt;/p&gt;&lt;p&gt;You can see the full JavaScript code for all 4 rotating cubes here: &lt;a href="https://glitch.com/edit/#!/gimbal-lock-quaternions?path=index.html%3A51%3A37"&gt;https://glitch.com/edit/#!/gimbal-lock-quaternions?path=index.html%3A51%3A37&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Generalizing to N-dimensions&lt;/h3&gt;&lt;p&gt;To generalize this solution to higher dimensions we need two things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A way to represent rotations. So far in 3D we’ve used 3x3 matrices and quaternions.&lt;/li&gt;&lt;li&gt;A way to describe a rotation around an arbitrary axis.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;Side note: it’s more generalizable to talk about “rotating within a plane” instead of “rotating around an axis”. In 2D there is only one plane of rotation, the XY plane. In 3D there are 3 planes of rotation. In 4D there are 6 planes. In N-D there are (N choose 2) planes.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I ended up choosing 4x4 matrices to represent my rotations, because 4x4 matrix operations are supported on the GPU and so I could rotate the geometry in my vertex shader, in the same way I would in 3D.&lt;/p&gt;&lt;p&gt;So the proposed solution is:&lt;/p&gt;&lt;pre&gt;rotationThisFrame = Matrix4.fromAxisAngle(0.05, arbitraryAxis);&lt;/pre&gt;&lt;pre&gt;cubeRotation = cubeRotation * rotationThisFrame;&lt;/pre&gt;&lt;p&gt;Now the tricky part is implementing a &lt;strong&gt;Matrix4.fromAxisAngle&lt;/strong&gt; function. It’s much easier to create a 4x4 rotation matrix for each of the 6 planes of rotations and compose them. So this can be broken down into:&lt;/p&gt;&lt;pre&gt;// Check which key(s) were pressed. In this frame, only the key for rotating in the XZ plane was pressed, so the rXZ 4x4 matrix gets a non-zero angle. &lt;/pre&gt;&lt;pre&gt;rXY = Matrix4.fromXYRotation(0);&lt;br&gt;rXZ = Matrix4.fromXZRotation(0.05);&lt;br&gt;rYZ = Matrix4.fromYZRotation(0);&lt;br&gt;rXW = Matrix4.fromXWRotation(0);&lt;br&gt;rYW = Matrix4.fromYWRotation(0);&lt;br&gt;rZW = Matrix4.fromZWRotation(0);&lt;/pre&gt;&lt;pre&gt;rotationThisFrame = rXY * rXZ * rYZ * XW * rYW * rZW;&lt;/pre&gt;&lt;pre&gt;cubeRotation = cubeRotation * rotationThisFrame;&lt;/pre&gt;&lt;p&gt;This looks suspiciously like Euler angles, but it’s not. This will never gimbal lock. No matter what orientation the cube ends up in, we can always rotate it by 0.05 radians in any of the 6 planes.&lt;/p&gt;&lt;p&gt;To illustrate the difference, here’s a version that will gimbal lock:&lt;/p&gt;&lt;pre&gt;// Check which key(s) were pressed. In this frame, only the key for the rotating in the XZ plane was pressed, so we add 0.05 to angle2.&lt;/pre&gt;&lt;pre&gt;angle2 += 0.05;&lt;/pre&gt;&lt;pre&gt;rXY = Matrix4.fromXYRotation(angle1);&lt;br&gt;rXZ = Matrix4.fromXZRotation(angle2);&lt;br&gt;rYZ = Matrix4.fromYZRotation(angle3);&lt;br&gt;rXW = Matrix4.fromXWRotation(angle4);&lt;br&gt;rYW = Matrix4.fromYWRotation(angle5);&lt;br&gt;rZW = Matrix4.fromZWRotation(angle6);&lt;/pre&gt;&lt;pre&gt;cubeRotation = rXY * rXZ * rYZ * XW * rYW * rZW;&lt;/pre&gt;&lt;p&gt;Beyond 4D, you could continue using NxN rotation matrices, but since GPUs don’t support that, I’d use &lt;a href="https://github.com/weshoke/versor.js/#creating-objects"&gt;rotors from Geometric Algebra&lt;/a&gt; to simplify implementation, which is how you generalize quaternions to higher dimensions.&lt;/p&gt;&lt;p&gt;I hope you’ve found this post useful in illustrating how to avoid gimbal lock, regardless of how you choose to represent your rotations.&lt;/p&gt;&lt;p&gt;If you want to learn more about my 4D geometry work, &lt;a href="https://www.youtube.com/watch?v=PdFU1Sb4NOs&amp;amp;list=PLE7tQUdRKcyY8jRx5khZf2uGW2nuBw3GQ&amp;amp;index=23"&gt;check out my talk at !!Con&lt;/a&gt;. If you’ve found an error in my explanation or something is unclear, you can find me on Twitter &lt;em&gt;(&lt;/em&gt;&lt;a href="https://twitter.com/omar4ur"&gt;&lt;em&gt;https://twitter.com/omar4ur&lt;/em&gt;&lt;/a&gt;&lt;em&gt;).&lt;/em&gt;&lt;/p&gt;&lt;img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=f2f7baec2b5e" width="1" height="1" alt=""&gt;</description>
        </item><item>
      <title>Handmade GitHub Pages</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Wed, 07 Jan 2026 14:50:03 +0000</pubDate>
      <link>https://dev.to/omar4ur/handmade-github-pages-20pi</link>
      <guid>https://dev.to/omar4ur/handmade-github-pages-20pi</guid>
      <description>&lt;p&gt;This is part 2 of the "handmade computational sandbox" class. In part 1 (&lt;a href="https://dev.to/omar4ur/handmade-cellular-automata-1f3c"&gt;https://dev.to/omar4ur/handmade-cellular-automata-1f3c&lt;/a&gt;) we learned how to run a piece of JS code in a single HTML file on your computer, and how to deploy it on CodePen to share. &lt;/p&gt;

&lt;p&gt;Today we're going to use GitHub for free static hosting, instead of CodePen. CodePen is good for quick experiments, GitHub is good for long term hosting. &lt;/p&gt;

&lt;p&gt;For example, if you run a local community and want to set up a web page for it, a simple HTML page + a GitHub repo is perfect because (1) it's 100% free (2) if one day you leave town, the source code is available so someone else can copy it and continue to host it. This is designed to be very &lt;a href="https://wiki.xxiivv.com/site/permacomputing.html" rel="noopener noreferrer"&gt;"permacomputing"&lt;/a&gt; and in line with Derek Siver's &lt;a href="https://sive.rs/ti" rel="noopener noreferrer"&gt;tech independence&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Example of a local community website made this way (just a single HTML file): &lt;a href="https://mplawley.github.io/tundra-tech-talks/" rel="noopener noreferrer"&gt;https://mplawley.github.io/tundra-tech-talks/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're sharing a research prototype, this is also the perfect way to do it (live demo + source code available + a space for people to ask questions on the GitHub repo)&lt;/p&gt;




&lt;p&gt;We're going to take the HTML/JS cellular automata simulation we created in part 1 and host it on GitHub pages. If you don't have your file from part 1, you can use this one that implements the game of life rules:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.githubusercontent.com/OmarShehata/9215085ff48882d1756ddd5ce2e0b912/raw/6ec921b6abd3dfc9f52a9be45989334cb1bb3c15/game_of_life.html" rel="noopener noreferrer"&gt;https://gist.githubusercontent.com/OmarShehata/9215085ff48882d1756ddd5ce2e0b912/raw/6ec921b6abd3dfc9f52a9be45989334cb1bb3c15/game_of_life.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a new GitHub repo&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login or create an account on &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;https://github.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click "+" button in the top right -&amp;gt; "New repository"&lt;/li&gt;
&lt;li&gt;Give it a name, toggle the "Add README" button. Click "create repository"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Add your HTML file&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the "+" button in the top right of the repo and "create new file"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jue1r9uu8sfohfyae2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jue1r9uu8sfohfyae2q.png" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call it &lt;code&gt;index.html&lt;/code&gt;, and paste in your HTML/JS code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo2iqhhd1j3p8zk4s9jf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo2iqhhd1j3p8zk4s9jf.png" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"index.html" is a special name, web servers will default to serving this as the homepage if they find it in a directory. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click "commit changes"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Tell GitHub to deploy this website&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to "settings" in the top right &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ufj3ztn8d2qgasj1qux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ufj3ztn8d2qgasj1qux.png" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then "pages" in the left side panel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitiz9c0u1cwexmiebvbl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitiz9c0u1cwexmiebvbl.png" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you will find the default settings for GitHub Pages, "deploy from branch". Just select your main branch here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcykub65fgzpvmj80ae69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcykub65fgzpvmj80ae69.png" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For bigger projects, you will have the code be in one branch, and the "built" thing to deploy in a different branch. For now, the code we are writing is itself the final code that runs in the browser, so we don't need this build step ("GitHub Actions" can be configured to run these build steps for you)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hit "save"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Check the deployment status&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it worked, you should see this yellow circle back in the main repo page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8f2vzmgcuy9fsf9exb12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8f2vzmgcuy9fsf9exb12.png" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can click on it to check the status. Once it's done, you can get the URL for your deployed website back in the Settings &amp;gt; Pages &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fph4mtk18wsuyy74fu1td.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fph4mtk18wsuyy74fu1td.png" alt=" " width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>handmade</category>
      <category>vanilla</category>
    </item><item>
      <title>Handmade Cellular Automata</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Tue, 06 Jan 2026 18:59:09 +0000</pubDate>
      <link>https://dev.to/omar4ur/handmade-cellular-automata-1f3c</link>
      <guid>https://dev.to/omar4ur/handmade-cellular-automata-1f3c</guid>
      <description>&lt;p&gt;This tutorial will walk you through creating &amp;amp; deploying your first "computational sandbox", an environment where you can define the rules of a simulation and explore the result. This is designed to be walked through together with a mentor.  &lt;/p&gt;

&lt;p&gt;This is the opposite of vibe coding - in order for you to use these simulations to think &amp;amp; learn about the world, you need to know everything about how it works. This is why we're doing everything "by hand". We're going to do the absolute minimum setup you need to (1) run things on a computer by yourself (2) share it with collaborators in a way that they can edit and build on. &lt;/p&gt;

&lt;h3&gt;
  
  
  Inspirations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://wiki.xxiivv.com/site/permacomputing.html" rel="noopener noreferrer"&gt;Permacomputing&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Derek Sivers' &lt;a href="https://sive.rs/ti" rel="noopener noreferrer"&gt;"tech independence"&lt;/a&gt; philosophy

&lt;ul&gt;
&lt;li&gt;See also &lt;a href="https://0data.app/en/" rel="noopener noreferrer"&gt;Rosano's Zero Data Apps&lt;/a&gt; &amp;amp; the &lt;a href="https://kosmos.org/" rel="noopener noreferrer"&gt;Kosmos&lt;/a&gt; network &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Casey Muratori's &lt;a href="https://www.computerenhance.com/about" rel="noopener noreferrer"&gt;"Handmade Hero"&lt;/a&gt; series &lt;/li&gt;

&lt;li&gt;

&lt;a href="https://explorabl.es/" rel="noopener noreferrer"&gt;Explorable Explanations&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;Like the &lt;a href="https://ncase.me/polygons/" rel="noopener noreferrer"&gt;Parable of Polygons&lt;/a&gt;, a simulation about how sociology &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ciechanow.ski/cameras-and-lenses/" rel="noopener noreferrer"&gt;Cameras &amp;amp; Lenses&lt;/a&gt;, simulation about how cameras, light, and vision work&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Internet art experiments like those done by Nolan (&lt;a href="https://eieio.games/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://eieio.games/" rel="noopener noreferrer"&gt;https://eieio.games/&lt;/a&gt;) &amp;amp; Neal (&lt;a href="https://neal.fun/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://neal.fun/" rel="noopener noreferrer"&gt;https://neal.fun/&lt;/a&gt;). See &lt;a href="https://newslettergoeshere.substack.com/p/projects-for-november-2025" rel="noopener noreferrer"&gt;Nolan's newsletter&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Example of a simple research prototype that is only a few lines of code &amp;amp; a single HTML file, &lt;a href="https://github.com/DefenderOfBasic/good-and-evil-concepts?tab=readme-ov-file#polarized-words" rel="noopener noreferrer"&gt;good &amp;amp; evil words&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Overview of the series
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;(this article) How to run a piece of code in a plain HTML file on your computer, and deploy it on the internet with CodePen&lt;/li&gt;
&lt;li&gt;Deploying a free static website or app on GitHub pages, like &lt;a href="https://ithacasocialcircle.com/" rel="noopener noreferrer"&gt;Ithaca Social Circle&lt;/a&gt;, or an &lt;a href="https://dev.to/defenderofbasic/host-your-obsidian-notebook-on-github-pages-for-free-8l1"&gt;Obsidian based website "digital garden"&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/omar4ur/handmade-github-pages-20pi"&gt;https://dev.to/omar4ur/handmade-github-pages-20pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;mdBook template &lt;a href="https://github.com/OmarShehata/mdbook-template/tree/main?tab=readme-ov-file#mdbook-template" rel="noopener noreferrer"&gt;https://github.com/OmarShehata/mdbook-template/tree/main?tab=readme-ov-file#mdbook-template&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Very basic backends ((1) using Google Sheets as a free backend, (2) or "BYO server" with &lt;a href="https://remotestorage.io/" rel="noopener noreferrer"&gt;remoteStorage&lt;/a&gt;, or (3) free CloudFlare object storage)&lt;/li&gt;
&lt;li&gt;Basic user management with OAuth (twitter/google login)&lt;/li&gt;
&lt;li&gt;Basic computer graphics visualizations (how to render pixels "raw", how to use a library like PixiJS or ThreeJS)&lt;/li&gt;
&lt;li&gt;Basic data analysis (Jupyter notebooks &amp;amp; Google Colab)

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://colab.research.google.com/drive/109XOgTWj-sajpAYhDCNPfts5zvdkpi_s" rel="noopener noreferrer"&gt;Simple twitter data NLP analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://distill.pub/2020/growing-ca/" rel="noopener noreferrer"&gt;ML cellular automata&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tips for navigating open source codebases, how to fork, edit, and contribute a pull request&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;In this lesson, you're going to setup this cellular automata simulation as a single HTML file on your computer, and copy/paste it onto CodePen to share it on the internet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcps8mmkrawuazx38ayvo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcps8mmkrawuazx38ayvo.gif" width="500" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Install VS Studio Code
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;https://code.visualstudio.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will use this as our IDE to edit code. The web browser is what will "run" the code.&lt;/p&gt;

&lt;p&gt;You can use VS Code to edit any coding language, by either running the code outside of it, or finding a plugin that runs it for you.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create an HTML file
&lt;/h4&gt;

&lt;p&gt;This is just a text file with the extension &lt;code&gt;.html&lt;/code&gt;. Inside of the HTML code we will embed the JavaScript code we want to run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the file &lt;code&gt;vanilla.html&lt;/code&gt; with VS Code, anywhere on your computer&lt;/li&gt;
&lt;li&gt;Paste in the following code
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vanilla JS&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// This is how you embed JavaScript inside of HTML&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: This series will not cover the basics of JS syntax. It's assumed you have a supplementary source or already know it. I recommend the book &lt;a href="https://eloquentjavascript.net/" rel="noopener noreferrer"&gt;Eloquent Javascript&lt;/a&gt;, and the &lt;a href="https://www.codecademy.com/courses/introduction-to-javascript/lessons/introduction-to-javascript/exercises/console" rel="noopener noreferrer"&gt;Codecademy JavaScript interactive lessons&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run this code by opening this file in your browser&lt;/li&gt;
&lt;li&gt;Check the browser console to see if the JS code snippet ran correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Challenge&lt;/strong&gt;: Can you make the web page display the current time?&lt;/p&gt;

&lt;p&gt;You want to (1) get the current time in the JS code (2) Use &lt;code&gt;document.querySelector()&lt;/code&gt; to select the HTML element and edit it with the local time (3) use &lt;code&gt;setInterval&lt;/code&gt; to auto-update the code&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.githubusercontent.com/OmarShehata/9215085ff48882d1756ddd5ce2e0b912/raw/66a321e74766caa6681d3b532c525abbd8c3cb77/vanilla_date.html" rel="noopener noreferrer"&gt;Solution&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Note: You can use the browser console as a REPL! You can expose a variable from your code by saying &lt;code&gt;window.myVar = myVar&lt;/code&gt;, and then you have access to editing it live in your app&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Deploy your code on the internet
&lt;/h4&gt;

&lt;p&gt;This is the fastest way to get your code to run on millions of devices. It's "infinitely" scalable because the code runs on the user's computer, not on a central server. It's very cheap for CodePen, or any static host, because it's just delivering the code (consuming bandwidth, not CPU). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make an account on &lt;a href="https://codepen.io/" rel="noopener noreferrer"&gt;https://codepen.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new "pen"&lt;/li&gt;
&lt;li&gt;Copy/paste your code into the "HTML" section of the CodePen interface&lt;/li&gt;
&lt;li&gt;Click "Save" in the top right&lt;/li&gt;
&lt;li&gt;To share it, click on the little icon of an arrow going out of a box, in the bottom right (on the same row as "Share" / "Export" / "Embed")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The shared link should look like this: &lt;a href="https://codepen.io/omarshe7ta/full/wBWBqZq" rel="noopener noreferrer"&gt;https://codepen.io/omarshe7ta/full/wBWBqZq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can continue writing code in the CodePen interface, or locally in VS Code.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Animated rectangle
&lt;/h4&gt;

&lt;p&gt;Now we're going to run a piece of code that draws a rectangle that moves back and forth. Technically, the rectangle doesn't "move", we just erase the screen and redraw the rectangle at a new location at every frame. &lt;/p&gt;

&lt;p&gt;Replace the code you have with this new template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vanilla JS&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- the "canvas" element is the box on the page, inside of which all the drawing will happen --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;canvas&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// set the height &amp;amp; width to be full screen&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;positionX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Clear the screen&lt;/span&gt;
            &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;// Draw a rectangle, x, y, width, height&lt;/span&gt;
            &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;positionX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// move the position for the next frame&lt;/span&gt;
            &lt;span class="nx"&gt;positionX&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

            &lt;span class="c1"&gt;// run the function "loop" again&lt;/span&gt;
            &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// run the function "loop" once&lt;/span&gt;
        &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Can you move the box faster? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Can you make the box start at the right edge of the screen and move to the left&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Can you make the box move back &amp;amp; forth?&lt;/p&gt;

&lt;p&gt;To do this, set the X of the box to be the sine of your count variable. Sine of any number will give you a range of [-1, 1], and you can scale that to the range you want it to go back and forth in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.githubusercontent.com/OmarShehata/9215085ff48882d1756ddd5ce2e0b912/raw/e3dfab1883cd1d6b13da75adb423176ade24ea48/vanilla_sine.html" rel="noopener noreferrer"&gt;Solution&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  5. Cellular Automata Grid
&lt;/h4&gt;

&lt;p&gt;Here we're going to start with a piece of code that sets up a grid of pixels with a random color. We'll use this as a base to explore various "cellular automata" simulations, like the &lt;a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" rel="noopener noreferrer"&gt;Game of Life&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace the code you have with this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Vanilla JS&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;canvas&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
        &lt;span class="nf"&gt;initGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nf"&gt;updateGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;drawGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Fill the grid data structure with initial random colors&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;
                    &lt;span class="nx"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="c1"&gt;// modify the color of the current square&lt;/span&gt;
                    &lt;span class="c1"&gt;// given the color it currently has&lt;/span&gt;
                    &lt;span class="nx"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;drawGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// draw whatever is currently stored in the grid variable&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hsl(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 70%, 60%)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try changing the &lt;code&gt;gridSize&lt;/code&gt; variable at the top. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Expose the &lt;code&gt;grid&lt;/code&gt; variable to the browser console, so you can edit it in "real-time". Ask your LLM for a one-liner to take this data structure and set it all to 0, or some other constant&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Edit the &lt;code&gt;updateGrid&lt;/code&gt; function to make the color change every frame &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Edit the &lt;code&gt;updateGrid&lt;/code&gt; function to set the color of the current pixel, equal to the pixel to its left.&lt;/p&gt;

&lt;p&gt;You'll need to handle the boundary condition to avoid errors.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Next lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/omar4ur/handmade-github-pages-20pi"&gt;Deploy with GitHub Pages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>handmade</category>
      <category>vanilla</category>
    </item><item>
      <title>Open source semantic embedding, search &amp; clustering in NodeJS</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Wed, 25 Sep 2024 15:43:24 +0000</pubDate>
      <link>https://dev.to/omar4ur/open-source-semantic-embedding-search-clustering-in-nodejs-23om</link>
      <guid>https://dev.to/omar4ur/open-source-semantic-embedding-search-clustering-in-nodejs-23om</guid>
      <description>&lt;p&gt;This tutorial walks you through how to do semantic embedding completely offline with open source models in NodeJS. No knowledge of AI/ML is required. Source code: &lt;a href="https://github.com/OmarShehata/minimal-embedding-template" rel="noopener noreferrer"&gt;https://github.com/OmarShehata/minimal-embedding-template&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An "embedding" is a high dimensional vector &lt;code&gt;(x,y,z,...)&lt;/code&gt; that represents a concept. Think of it as the internal representation of words in an LLM. You can compute distances between these vectors.&lt;/p&gt;

&lt;p&gt;Example: "Man" is much closer to "boy" &amp;amp; "woman", compared to "chicken". "Coffee" and "wifi"  are somewhat close, and are both close to "coffee shop". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni5gmzofgmlo00ryakgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni5gmzofgmlo00ryakgn.png" alt="illustration of what these vectors might look like projected down to 2D" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;
illustration of what these vectors might look like projected down to 2D



&lt;p&gt;I think this is an extremely underutilized feature of modern LLM's, and it's much cheaper compute wise compared to text generation. Most of the time I don't really want the LLM to generate text as much as I want to see &amp;amp; manipulate the semantic concepts like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Clone the repo: &lt;a href="https://github.com/OmarShehata/semantic-embedding-template" rel="noopener noreferrer"&gt;https://github.com/OmarShehata/semantic-embedding-template&lt;/a&gt;. This contains a minimal NodeJS template that you can copy/paste and build on.&lt;/p&gt;

&lt;p&gt;It uses (1) &lt;a href="https://www.npmjs.com/package/gpt4all" rel="noopener noreferrer"&gt;gpt4all&lt;/a&gt; as the LLM engine. This is where the open source model comes from, and is what converts a word/string/document into a vector. (2) &lt;a href="https://github.com/Stevenic/vectra/" rel="noopener noreferrer"&gt;Vectra&lt;/a&gt; as a local, single file vector database. Allows us to index &amp;amp; search vectors. &lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;pnpm install&lt;/code&gt;, then run the first example in &lt;code&gt;example-simple-embedding/index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm simple-embedding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This takes an array of strings and converts them to vectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertText&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;coffee shop&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wifi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can print the vectors with &lt;code&gt;embeddings.getTextMap()&lt;/code&gt;. You can do a search as shown below. This returns a sorted list of the closest vectors in the DB, along with the cosine distance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;coffee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// returns:&lt;/span&gt;
&lt;span class="c1"&gt;// [&lt;/span&gt;
&lt;span class="c1"&gt;//   [ 'coffee shop', 0.8214959697396015 ],&lt;/span&gt;
&lt;span class="c1"&gt;//   [ 'wifi', 0.711907901740376 ],&lt;/span&gt;
&lt;span class="c1"&gt;//   [ 'hard work', 0.6709908415581982 ],&lt;/span&gt;
&lt;span class="c1"&gt;//   [ 'love peace &amp;amp; joy, relaxation', 0.6495931802131457 ]&lt;/span&gt;
&lt;span class="c1"&gt;// ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(&lt;code&gt;1&lt;/code&gt; means it's exactly the same vector, &lt;code&gt;-1&lt;/code&gt; means it's exactly opposite, &lt;code&gt;0&lt;/code&gt; means no correlation)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;embeddings&lt;/code&gt; is a thin wrapper around gpt4all
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/OmarShehata/semantic-embedding-template/blob/main/lib/embeddings.js" rel="noopener noreferrer"&gt;lib/embeddings.js&lt;/a&gt; implements &lt;code&gt;insertText&lt;/code&gt; which:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;checks to see if these words are already in the DB&lt;/li&gt;
&lt;li&gt;inserts them if they are not, with a batch update&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;search&lt;/code&gt; function takes the query string and converts it to a vector, then runs a query with the vectra DB.&lt;/p&gt;

&lt;p&gt;The specific model I'm using here is &lt;a href="https://huggingface.co/nomic-ai/nomic-embed-text-v1.5" rel="noopener noreferrer"&gt;nomic-embed-text-v1.5&lt;/a&gt; which is an open source model &amp;amp; free to use model that runs locally on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenAI embeddings
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/OmarShehata/semantic-embedding-template/blob/main/lib/embeddings-openai.js" rel="noopener noreferrer"&gt;lib/embeddings-openai.js&lt;/a&gt; is a version of this file that has exactly the same API but sends the text to OpenAI. See &lt;a href="https://platform.openai.com/docs/guides/embeddings/what-are-embeddings" rel="noopener noreferrer"&gt;OpenAI's embedding docs&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The OpenAI model captures more nuance in my experience (for example, it captures the semantic meaning of emojis whereas the open source one doesn't seem to).&lt;/p&gt;

&lt;p&gt;Set the &lt;code&gt;OPEN_API_KEY&lt;/code&gt; environment variable to use this. To run the example in &lt;code&gt;example-openai-embedding/index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm openai-embedding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Clustering
&lt;/h2&gt;

&lt;p&gt;To run &lt;a href="https://github.com/OmarShehata/semantic-embedding-template/blob/main/example-clustering/index.js" rel="noopener noreferrer"&gt;&lt;code&gt;example-clustering/index.js&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm clustering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This clusters the vectors in the DB using k-means. You tell it the number of clusters you want to create, and it iterates over each point to find the "k nearest neighbors" to create these clusters.&lt;/p&gt;

&lt;p&gt;Normally, you don't know how many clusters are in the data. There's various techniques to find this. One way is the "elbow method" where you cluster the dataset for increasingly higher cluster sizes and compute a "score". The score represents how close all items in the cluster are to a centroid. So the lower the score the more you end up with clusters of semantically related things.&lt;/p&gt;




&lt;p&gt;I hope you found this useful! You can use the base code here to basically recreate Neal's &lt;a href="https://neal.fun/infinite-craft/" rel="noopener noreferrer"&gt;Infinite Craft&lt;/a&gt; game. Basically put all the words in the dictionary in the vector database. Then to combine two words, add the vectors (or get the average?), then search for the closest thing to that combined vector. &lt;/p&gt;

&lt;p&gt;This is my personal sandbox that I hope to add more stuff to. For example, there are models that can convert an image to a text description. You can then get a vector embedding for that text, and with that you can build an app where you can "CTRL+F" for your images (again, all offline, and free!)&lt;/p&gt;

</description>
      <category>node</category>
      <category>ai</category>
      <category>vectordatabase</category>
      <category>javascript</category>
    </item><item>
      <title>Build &amp; deploy your first web app</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Fri, 14 Jul 2023 00:28:09 +0000</pubDate>
      <link>https://dev.to/omar4ur/build-deploy-your-first-web-app-48dk</link>
      <guid>https://dev.to/omar4ur/build-deploy-your-first-web-app-48dk</guid>
      <description>&lt;p&gt;This guide is written for students going through &lt;a href="https://labs.codeday.org/" rel="noopener noreferrer"&gt;CodeDay Labs&lt;/a&gt;. You will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to set up a simple web app from scratch &lt;/li&gt;
&lt;li&gt;How to deploy your applications so others can access it via a URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial is meant to teach the basic fundamentals of working with web technologies, regardless of what specific framework you might be using in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Create an HTML page
&lt;/h3&gt;

&lt;p&gt;We are going to create our first web page, by hand. You typically will not do this in your web development career, but it will help you understand what is happening under the hood, and what problems all these frameworks like React etc are trying to help you solve.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new directory for our project. Name it &lt;code&gt;web-dev-101&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open up your favorite code editor, like VSCode or Sublime Text, and create a new file called &lt;code&gt;index.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy/paste the following code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Web Dev 101&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now preview your web page by double clicking on &lt;code&gt;index.html&lt;/code&gt;, or dragging and dropping it into your web browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fst9ghlg4y4bf9051mtwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fst9ghlg4y4bf9051mtwh.png" alt=" " width="713" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Extra challenges:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;What does the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag mean? What happens if you do &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; tag instead? Or &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag?&lt;/li&gt;
&lt;li&gt;Can you change the title in the browser tab, to make it say &lt;code&gt;Web Dev 102&lt;/code&gt; instead of &lt;code&gt;Web Dev 101&lt;/code&gt; ?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2 - Add some styling / CSS
&lt;/h3&gt;

&lt;p&gt;HTML is a markup language, it's for controlling &lt;strong&gt;what&lt;/strong&gt; is shown on screen (as in, the content, the text, etc)&lt;/p&gt;

&lt;p&gt;CSS is the styling language, it controls &lt;strong&gt;how&lt;/strong&gt; things are displayed on screen (the color, the size, etc)&lt;/p&gt;

&lt;p&gt;To add CSS/styling rules to your web page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the following snippet inside the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should go like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv69yvps0sub4xuhhwjro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv69yvps0sub4xuhhwjro.png" alt=" " width="749" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then refresh your web page, the text should now be red:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5eg31due4v034j489u7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5eg31due4v034j489u7l.png" alt=" " width="568" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This CSS rule we added makes ALL &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tags red. If we wanted to make a specific HTML element red, we have to give it either an ID or a class.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give your &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; element an id:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Change your CSS rule to target the element with the id &lt;code&gt;title&lt;/code&gt; instead of all &lt;code&gt;h1&lt;/code&gt; tags:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#&lt;/code&gt; symbol prefixing "title" is what tells CSS to apply the rule to any element that has the ID "title". This is called a &lt;strong&gt;CSS selector&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another common type of CSS selector is a class. It works very similarly to an ID. You can give an element a class name as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h2 class="subtitle"&amp;gt;My subtitle&amp;lt;/h2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can style it like this in CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.subtitle {
  color: blue;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When should you use id vs class? Typically you use id for one specific element (like the title) and a class for something for which there can be multiple elements (like a paragraph, or a button).&lt;/p&gt;

&lt;h4&gt;
  
  
  Extra challenges:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;What happens if you have an element that is BOTH an &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and has an id &lt;code&gt;title&lt;/code&gt;, and you create a css rule that makes &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; red and a css rule that makes &lt;code&gt;title&lt;/code&gt; elements blue? Will the element be red or blue?&lt;/li&gt;
&lt;li&gt;Can you use CSS to make an element underlined? Or bigger font?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3 - Move your CSS to another file
&lt;/h3&gt;

&lt;p&gt;You can add CSS into the same file as your HTML. But for bigger projects it is helpful to split it up into another file.&lt;/p&gt;

&lt;p&gt;To do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the following line inside the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag, this tells the HTML page it should load styles from a file called &lt;code&gt;style.css&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a file called &lt;code&gt;style.css&lt;/code&gt; and move your CSS in there. It might look like this:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vnanr6ve9kitd1aqo5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vnanr6ve9kitd1aqo5v.png" alt=" " width="578" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Refresh the web page, confirm the CSS still works. Make a change to the style/color and confirm it updates when you refresh.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4 - Deploy your web page
&lt;/h3&gt;

&lt;p&gt;At this point the web page only exists on your computer. In order for others to access it on the internet, we need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put it on a web server&lt;/li&gt;
&lt;li&gt;Give it on a domain name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A "web server" is just a computer. Your personal laptop &lt;em&gt;could&lt;/em&gt; be a web server. You just need to run a program that responds to HTTP requests and returns your web page. &lt;/p&gt;

&lt;p&gt;In fact, let's try that real quick:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install a simple &lt;a href="https://www.npmjs.com/package/http-server" rel="noopener noreferrer"&gt;http server library&lt;/a&gt; by running the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --global http-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(if you don't already have npm installed, get it from here: &lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;https://nodejs.org/en/download&lt;/a&gt;. Yarn is also fine, the command might be slightly different.)&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open up a terminal window in the folder of your &lt;code&gt;index.html&lt;/code&gt; and run the following command to run a web server on your laptop:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http-server .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dot (&lt;code&gt;.&lt;/code&gt;) tells it to serve the HTML files in the current directory.&lt;/p&gt;

&lt;p&gt;This should give you an output that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available on:
  http://172.25.240.1:8080
  http://192.168.1.147:8080
  http://127.0.0.1:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open up the &lt;strong&gt;second&lt;/strong&gt; URL in your web browser (for me that's &lt;code&gt;http://192.168.1.147:8080&lt;/code&gt;). You should see your website.&lt;/li&gt;
&lt;li&gt;If it works, open up this URL on your phone or another computer. As long as it's connected to the same WiFi as your laptop, it should work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What you just did is access your web page on your phone, powered by the web server running on your laptop!&lt;/p&gt;

&lt;p&gt;You don't have a domain name, which is why you have to access it trough the IP address of your computer. It has to be on the same WiFi network for reasons outside the scope of this tutorial.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 - Deploy to a web server with a domain name
&lt;/h3&gt;

&lt;p&gt;To put your web page on a server that others can access anywhere on the internet, we typically need to pay for this service. There's a few free options. One free option is: &lt;a href="https://glitch.com/" rel="noopener noreferrer"&gt;https://glitch.com/&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an account on &lt;a href="https://glitch.com/signup" rel="noopener noreferrer"&gt;https://glitch.com/signup&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new project (top right of the page)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitolbqmtb3m4gr6joy9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fitolbqmtb3m4gr6joy9q.png" alt=" " width="690" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select the first option &lt;strong&gt;glitch-hello-website&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will take you to the Glitch code editor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy paste your &lt;code&gt;index.html&lt;/code&gt; from your computer into the Glitch editor (select index.html from the sidebar then just replace all its contents)&lt;/li&gt;
&lt;li&gt;Do the same for &lt;code&gt;style.css&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Click the "Preview" button in the bottom panel to open up your website:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uczb2d2s7luh5qsaue9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uczb2d2s7luh5qsaue9.png" alt=" " width="548" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is your website deployed to a web server, with a domain name you can now share!&lt;/p&gt;

&lt;h4&gt;
  
  
  Extra challenges:
&lt;/h4&gt;

&lt;p&gt;Another option instead of using Glitch is using Github Pages. This is a way of automatically getting a deployed web page for any repository in your GitHub account.&lt;/p&gt;

&lt;p&gt;The following guide will explain how to do it. Try to create a new repository for your &lt;code&gt;web-dev-101&lt;/code&gt; project and deploy it with GitHub pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pages.github.com/" rel="noopener noreferrer"&gt;https://pages.github.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item><item>
      <title>Vite Hot Module Replacement - A Complete Example</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Sun, 17 Apr 2022 15:45:21 +0000</pubDate>
      <link>https://dev.to/omar4ur/vite-hot-module-replacement-a-complete-example-pkg</link>
      <guid>https://dev.to/omar4ur/vite-hot-module-replacement-a-complete-example-pkg</guid>
      <description>&lt;p&gt;This article explains how to set up hot module replacement (HMR) with Vite for a vanilla JS project. The goal is to be able to see changes in the code without refreshing or restarting the application.&lt;/p&gt;

&lt;p&gt;For me this is particularly useful in creative coding when I'm iteratively building a simulation and don't want to lose state as I make live changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa08hchvm37reavpfydxn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa08hchvm37reavpfydxn.gif" width="760" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Complete source code for this article here: &lt;a href="https://github.com/OmarShehata/vite-hot-reload-example" rel="noopener noreferrer"&gt;https://github.com/OmarShehata/vite-hot-reload-example&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of my implementation
&lt;/h2&gt;

&lt;p&gt;I'm going to show you how I've set up my HMR to make it as simple as possible to enable for new modules. In subsequent sections I'll break down how it works so you are aware of all the caveats and can use it in your project as needed.&lt;/p&gt;

&lt;p&gt;To enable HMR on any module, I add the event handler at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HMREventHandler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./HotModuleReloadSetup.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HMREventHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Vite to avoid refreshing the page when this module is updated, and instead fire an HMR event.&lt;/p&gt;

&lt;p&gt;Next, I have a singleton instance of &lt;code&gt;HotModuleReloadSetup&lt;/code&gt; that takes dynamically imported modules, and automatically swaps them out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HotModuleReloadSetup&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./HotModuleReloadSetup.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Setup HMR&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hmr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HotModuleReloadSetup&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Load a module that will be updated dynamically&lt;/span&gt;
&lt;span class="nx"&gt;hmr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Draw.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I now have access to an instance of the Draw class through &lt;code&gt;hmr.instances['Draw']&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the draw class defines a &lt;code&gt;hotReload&lt;/code&gt; handler. This passes a reference to the old instance so you can copy over any state variables to the new instance.&lt;/p&gt;

&lt;p&gt;So when I call &lt;code&gt;hmr.instances['Draw'].draw()&lt;/code&gt; in the render loop, it will always use the latest code.&lt;/p&gt;

&lt;p&gt;This pattern is modelled after how &lt;a href="https://developer.playcanvas.com/en/user-manual/scripting/hot-reloading/" rel="noopener noreferrer"&gt;PlayCanvas does their hot reloading&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Here is what happens when you make a change in an HMR module (&lt;code&gt;Draw.js&lt;/code&gt; in my case) &amp;amp; save the file:&lt;/p&gt;

&lt;p&gt;1 - Vite triggers an HMR event (which we've added a listener to via &lt;code&gt;import.meta.hot.accept&lt;/code&gt;)&lt;br&gt;
2 - I then dispatch a custom event on the DOM with that new module (this is in &lt;a href="https://github.com/OmarShehata/vite-hot-reload-example/blob/f831efd75129de25392e023d12fc2a171545c312/src/HotModuleReloadSetup.js#L36" rel="noopener noreferrer"&gt;HotModuleReloadSetup.js&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HMREventHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hot-module-reload&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;newModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows &lt;code&gt;HotModuleReloadSetup&lt;/code&gt; to listen for these events globally.&lt;/p&gt;

&lt;p&gt;3 - We search our map of &lt;code&gt;modules&lt;/code&gt; to see if the new module we received exists&lt;br&gt;
4 - If so, we create a new instance from the new module, call &lt;code&gt;newInstance.hotReload(oldInstance)&lt;/code&gt;, and discard the old module &amp;amp; old instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;swapModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oldModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oldInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;oldModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;newModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;newInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hotReload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldInstance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newModule&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newInstance&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you can access either one instance of a class that is always updated through the &lt;code&gt;instances&lt;/code&gt; map, or you can access the latest module through the &lt;code&gt;modules&lt;/code&gt; map. The latter can be used if your code is spawning many instances of a class (like enemies or bullets), and you want your live code changes to affect newly spawned instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you need to have multiple instances of a class that are all updated when the code changes, you'll need to keep an array of these instances and swap them all out in the same way &lt;code&gt;HotModuleReloadSetup.swapModule&lt;/code&gt; does&lt;/li&gt;
&lt;li&gt;If your HMR class needs constructor arguments, you'll need to store those in the global manager that creates the new instances so they can be passed to them as well.&lt;/li&gt;
&lt;li&gt;I turn off Rollup minification because it rewrites function names, but cannot update all uses of the function when using dynamic imports like this. That causes &lt;code&gt;hmr.instances['Draw'].draw()&lt;/code&gt; to break because the function name is no longer &lt;code&gt;draw&lt;/code&gt; in a production build.&lt;/li&gt;
&lt;li&gt;I import the module by name and pass it to &lt;code&gt;hmr.import()&lt;/code&gt; due to the limitations on dynamic imports in Vite, see: &lt;a href="https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations" rel="noopener noreferrer"&gt;https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading! I hope you found this useful. If you find a bug or a better way to streamline HMR, especially for creative coding, I'd love to hear. You can find me on Twitter: &lt;a href="https://twitter.com/omar4ur" rel="noopener noreferrer"&gt;https://twitter.com/omar4ur&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vite</category>
      <category>webdev</category>
      <category>productivity</category>
    </item><item>
      <title>How to create bitmap fonts for Phaser JS with BMFont</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Mon, 21 Feb 2022 12:55:21 +0000</pubDate>
      <link>https://dev.to/omar4ur/how-to-create-bitmap-fonts-for-phaser-js-with-bmfont-2ndc</link>
      <guid>https://dev.to/omar4ur/how-to-create-bitmap-fonts-for-phaser-js-with-bmfont-2ndc</guid>
      <description>&lt;p&gt;This guide explains how to generate bitmap fonts from TTF or OTF files for use in PhaserJS. I'll be using &lt;a href="https://www.angelcode.com/products/bmfont/" rel="noopener noreferrer"&gt;BMFont&lt;/a&gt; which is Windows only.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why bitmap fonts?
&lt;/h3&gt;

&lt;p&gt;The main use case is if you're creating a pixel art game &amp;amp; want your text to match the retro style and have no antialiasing. &lt;/p&gt;

&lt;p&gt;Below is an example from a recent game I made. The top is the standard font rendering in Phaser. The bottom is a bitmap version of the same font.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm013sgvqtkvqojn2a2gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm013sgvqtkvqojn2a2gt.png" width="730" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note the antialiasing inside letters like &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt;, or &lt;code&gt;o&lt;/code&gt;&lt;/strong&gt; in the top image. This creates what looks like blurry artifacts at the small scale of pixel art games. The bottom image has the crisp, pixelated rendering expected in retro games. &lt;/p&gt;

&lt;p&gt;Bitmap fonts may also be faster to render. &lt;a href="https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.BitmapText.html" rel="noopener noreferrer"&gt;From the Phaser docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability to use Web Fonts, however you trade this flexibility for rendering speed&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To use a bitmap font, Phaser needs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;An image&lt;/strong&gt; containing all the possible characters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An XML file&lt;/strong&gt; that defines the x/y/width/height of each character in the image. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's basically a spritesheet of letters.&lt;/p&gt;

&lt;p&gt;Here's an example I generated from this public domain font: &lt;a href="https://www.fontspace.com/public-pixel-font-f72305" rel="noopener noreferrer"&gt;https://www.fontspace.com/public-pixel-font-f72305&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The image with all the letters: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kzasgn1ardrb13xzz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kzasgn1ardrb13xzz3.png" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Snippet from the XML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;char&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"32"&lt;/span&gt; &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"507"&lt;/span&gt; &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;xoffset=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt; &lt;span class="na"&gt;yoffset=&lt;/span&gt;&lt;span class="s"&gt;"31"&lt;/span&gt; &lt;span class="na"&gt;xadvance=&lt;/span&gt;&lt;span class="s"&gt;"32"&lt;/span&gt; &lt;span class="na"&gt;page=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;chnl=&lt;/span&gt;&lt;span class="s"&gt;"15"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;char&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"33"&lt;/span&gt; &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"285"&lt;/span&gt; &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"87"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"18"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"28"&lt;/span&gt; &lt;span class="na"&gt;xoffset=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;yoffset=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt; &lt;span class="na"&gt;xadvance=&lt;/span&gt;&lt;span class="s"&gt;"32"&lt;/span&gt; &lt;span class="na"&gt;page=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;chnl=&lt;/span&gt;&lt;span class="s"&gt;"15"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;char&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"34"&lt;/span&gt; &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"441"&lt;/span&gt; &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"108"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"22"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt; &lt;span class="na"&gt;xoffset=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;yoffset=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt; &lt;span class="na"&gt;xadvance=&lt;/span&gt;&lt;span class="s"&gt;"32"&lt;/span&gt; &lt;span class="na"&gt;page=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;chnl=&lt;/span&gt;&lt;span class="s"&gt;"15"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can download this generated example in the format that Phaser can use here: &lt;a href="https://github.com/OmarShehata/webgl-outlines/files/8104312/pixel_bitmap_font.zip" rel="noopener noreferrer"&gt;pixel_bitmap_font.zip&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Download BMFont
&lt;/h3&gt;

&lt;p&gt;Download the executable on this page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.angelcode.com/products/bmfont/" rel="noopener noreferrer"&gt;https://www.angelcode.com/products/bmfont/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Load the font
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prepare your font as a TTF file or similar &lt;/li&gt;
&lt;li&gt;Open up &lt;code&gt;bmfont64.exe&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Options&lt;/code&gt; &amp;gt; &lt;code&gt;Font settings&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select your font file in &lt;code&gt;Add font file&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then select the name of the font in the &lt;code&gt;Font&lt;/code&gt; dropdown&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zpneejuo1l8x4c5g5rn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zpneejuo1l8x4c5g5rn.png" width="678" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your font is installed system-wide you can skip the &lt;code&gt;Add font file&lt;/code&gt; step and just select the name of the font directly.&lt;/p&gt;

&lt;p&gt;Now you should see your font loaded:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8spdeb607re5b4j0r8uu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8spdeb607re5b4j0r8uu.png" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Export
&lt;/h3&gt;

&lt;p&gt;First, we change the export settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;code&gt;Options&lt;/code&gt; &amp;gt; &lt;code&gt;Export options&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;XML&lt;/code&gt; as the Font descriptor&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;PNG&lt;/code&gt; as the textures option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vmd7zt5yzlbceqvbgme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vmd7zt5yzlbceqvbgme.png" width="672" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press OK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then to export:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select all letters for export (Ctrl + A)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;File&lt;/code&gt; &amp;gt; &lt;code&gt;Save bitmap font as&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will generate an XML file (it'll have the extension .fnt, you can rename that to .xml or leave it as-is, Phaser will be able to read it as an XML either way) and a PNG file. &lt;/p&gt;

&lt;p&gt;You may need to increase the width/height in the export options to keep all the letters in one image.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 - Use it in Phaser
&lt;/h3&gt;

&lt;p&gt;Tell Phaser where to load the PNG &amp;amp; XML files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load it&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bitmapFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bitmapFontName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;font.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;font.fnt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Add it to the scene&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bitmapText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bitmapFontName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lorem ipsum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;dolor sit amet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full example here: &lt;a href="https://labs.phaser.io/edit.html?src=src/loader/bitmap%20text/load%20bitmap%20text.js" rel="noopener noreferrer"&gt;https://labs.phaser.io/edit.html?src=src/loader/bitmap%20text/load%20bitmap%20text.js&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Final thoughts
&lt;/h3&gt;

&lt;p&gt;Note that a generated bitmap font has a font size baked in. Phaser can scale the font up and down but that may introduce artifacts in some cases. If you know the font size you want ahead of time you can set it in &lt;code&gt;Options&lt;/code&gt; &amp;gt; &lt;code&gt;Font settings&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I used a font size of 32px in my game which was big enough so that it still looked good when scaled down or up a bit.&lt;/p&gt;

&lt;p&gt;I hope you found this useful! If you have any corrections or find a better way to generate bitmap fonts for Phaser I'm happy to update this article. Find me on Twitter (&lt;a href="https://twitter.com/Omar4ur" rel="noopener noreferrer"&gt;@Omar4ur&lt;/a&gt;) or my website (&lt;a href="https://omarshehata.me/" rel="noopener noreferrer"&gt;https://omarshehata.me/&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>gamedev</category>
    </item><item>
      <title>Create a satellite tracker from scratch in 30 lines of JavaScript</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Thu, 06 May 2021 02:32:25 +0000</pubDate>
      <link>https://dev.to/omar4ur/create-a-satellite-tracker-from-scratch-in-30-lines-of-javascript-32gk</link>
      <guid>https://dev.to/omar4ur/create-a-satellite-tracker-from-scratch-in-30-lines-of-javascript-32gk</guid>
      <description>&lt;p&gt;This tutorial will walk you through how to create a web app that visualizes the location of any satellite in real-time, like the International Space Station. &lt;/p&gt;

&lt;p&gt;We're going to do this from scratch, using the same techniques a real rocket scientist would! &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We'll look at where to get the data about individual satellites that the government publishes, known as &lt;strong&gt;Two-Line Element Sets&lt;/strong&gt;, or TLE's. &lt;/li&gt;
&lt;li&gt;We'll use &lt;a href="https://github.com/shashwatak/satellite-js" rel="noopener noreferrer"&gt;satellite-js&lt;/a&gt; to predict the orbit of the satellite given the TLE's (this is the rocket science part).&lt;/li&gt;
&lt;li&gt;We'll use &lt;a href="https://github.com/CesiumGS/cesium#readme" rel="noopener noreferrer"&gt;CesiumJS&lt;/a&gt; to visualize the result, but you can use any library/engine that can take in longitude, latitude, and height. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below is a preview of the final result.&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/satellite-viewer?previewSize=100&amp;amp;path=index.html" alt="satellite-viewer on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;This is showing the path of the International Space Station, sped up by 40x. To &lt;strong&gt;see its current location in real-time&lt;/strong&gt;, click the clock icon at the top-left of the clock wheel. &lt;/p&gt;

&lt;p&gt;Here's a &lt;a href="https://satellite-viewer.glitch.me/" rel="noopener noreferrer"&gt;direct link to the app&lt;/a&gt;. And the &lt;a href="https://glitch.com/edit/#!/satellite-viewer" rel="noopener noreferrer"&gt;source code on Glitch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Get the satellite's Two-Line Element Set
&lt;/h2&gt;

&lt;p&gt;A Two-Line Element Set, or TLE, is a data format that describes the motion of an object orbiting the Earth. It was created by the North American Aerospace Defense Command (NORAD). You can &lt;a href="https://celestrak.com/columns/v04n03/" rel="noopener noreferrer"&gt;read more about it and its history here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Given this description of the orbit, we can predict the location of where it's going to be at any moment in time (which is step 2 below).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This means that most "live" satellite trackers are not live in the same way that tracking a delivery car on a map is&lt;/strong&gt;. Instead of relying on constantly receiving position updates, those who track objects in space will often get the latest TLE's (which are regularly updated) and use that to predict where the object is right now.&lt;/p&gt;

&lt;p&gt;Where do we get the TLE's? There is no one global official registry. Whoever owns the satellite and is monitoring it is responsible for updating and publishing the TLE for the benefit of the global space community (unless it's a spy satellite). &lt;/p&gt;

&lt;p&gt;We can find these TLE's on &lt;a href="https://www.space-track.org" rel="noopener noreferrer"&gt;Space Track&lt;/a&gt; which is a registry run by the United States Space Command. &lt;/p&gt;

&lt;p&gt;Another source is &lt;a href="https://celestrak.com/NORAD/elements/" rel="noopener noreferrer"&gt;this list on CeleStrak&lt;/a&gt; maintained by Dr. T.S. Kelso.&lt;/p&gt;

&lt;p&gt;We're going to use CeleStrak since it doesn't require a login. To find the TLE for the International Space Station, click on the &lt;a href="https://celestrak.com/NORAD/elements/stations.txt" rel="noopener noreferrer"&gt;Space Stations&lt;/a&gt; link. &lt;/p&gt;

&lt;p&gt;The first one is the TLE for the ISS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ISS (ZARYA)             
1 25544U 98067A   21122.75616700  .00027980  00000-0  51432-3 0  9994
2 25544  51.6442 207.4449 0002769 310.1189 193.6568 15.48993527281553
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The meaning of these numbers is &lt;a href="https://celestrak.com/columns/v04n03/#FAQ01" rel="noopener noreferrer"&gt;listed in table 1 in Dr T.S. Kelso's column&lt;/a&gt;. Most of them are identifiers and metadata about the satellite, like when it was launched. &lt;/p&gt;

&lt;p&gt;You can find TLE's for weather satellites, GPS satellites, and even &lt;a href="https://celestrak.com/NORAD/elements/starlink.txt" rel="noopener noreferrer"&gt;SpaceX's Starlink constellation&lt;/a&gt; in this same format.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 - Predict the satellite orbit
&lt;/h2&gt;

&lt;p&gt;Now that you know how to get the TLE of the object you're interested in tracking, the next step is converting that to a position in time.&lt;/p&gt;

&lt;p&gt;We're going to use &lt;a href="https://github.com/shashwatak/satellite-js" rel="noopener noreferrer"&gt;satellite-js&lt;/a&gt; for this. &lt;/p&gt;

&lt;p&gt;Include the library from a CDN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/satellite.js/4.0.0/satellite.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then pass the TLE to it, and a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ISS_TLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="s2"&gt;`1 25544U 98067A   21122.75616700  .00027980  00000-0  51432-3 0  9994
     2 25544  51.6442 207.4449 0002769 310.1189 193.6568 15.48993527281553`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Initialize the satellite record with this TLE&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;satrec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;satellite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;twoline2satrec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;ISS_TLE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; 
  &lt;span class="nx"&gt;ISS_TLE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Get the position of the satellite at the given date&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;positionAndVelocity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;satellite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;propagate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;satrec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gmst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;satellite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gstime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;satellite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eciToGeodetic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;positionAndVelocity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gmst&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;// in radians&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;// in radians&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;// in km&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the position of the satellite at the current time, &lt;code&gt;new Date()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This position is produced as a result of simulating a specific model of satellite motion. This model is called SGP4/SDP4. All TLE's assume this specific model. &lt;/p&gt;

&lt;p&gt;If you're wondering about the accuracy of this model, the short answer is, &lt;a href="https://celestrak.com/columns/v04n05/#FAQ06" rel="noopener noreferrer"&gt;it depends&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Accuracy of the two-line element sets is dependent upon a number of factors. These range from the particular sensors used and amount of data collected to the type of orbit and condition of the space environment. Unfortunately, since these factors vary for each element set, so does the accuracy. While NORAD has experimented with methods to incorporate prediction quality into the element sets, none of these methods has yet proved successful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3 - Visualize the result
&lt;/h2&gt;

&lt;p&gt;Now we have a way to get the location of any satellite, at any given time. We can pass in future times to animate its path, which we'll do in the next step.&lt;/p&gt;

&lt;p&gt;First, let's see how to visualize an individual point in space using CesiumJS.&lt;/p&gt;

&lt;p&gt;We load the library from CDN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cesium.com/downloads/cesiumjs/releases/1.81/Build/Cesium/Cesium.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cesium.com/downloads/cesiumjs/releases/1.81/Build/Cesium/Widgets/widgets.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And create a container element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cesiumContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then initialize the viewer. Here we pass in some extra options to disable functionality that requires an access token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Initialize the Cesium viewer.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;viewer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cesiumContainer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;imageryProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TileMapServiceImageryProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildModuleUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Assets/Textures/NaturalEarthII&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;baseLayerPicker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;geocoder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;homeButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;infoBox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;navigationHelpButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sceneModePicker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;globe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enableLighting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we'll visualize the satellite position as a red dot in space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;satellitePoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cartesian3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromRadians&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;pixelSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=simple.html" rel="noopener noreferrer"&gt;complete source code of this step in simple.html on Glitch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Animate the path
&lt;/h2&gt;

&lt;p&gt;To animate the path, we just need to sample more positions in the future. CesiumJS has a built-in way to interpolate between these samples over time.&lt;/p&gt;

&lt;p&gt;The setup for this is a bit verbose. &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=index.html%3A6%3A82" rel="noopener noreferrer"&gt;You can see the full code on Glitch&lt;/a&gt;. The important concepts are described below.&lt;/p&gt;

&lt;p&gt;We create a &lt;code&gt;SampledPositionProperty&lt;/code&gt;. This is an object that will hold position samples over time and will interpolate between them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;positionsOverTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SampledPositionProperty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We loop through however many samples we want to get, and for each sample, we construct a time object, called &lt;code&gt;JulianDate&lt;/code&gt; in CesiumJS, and a position, and we add that as a sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;timestepInSeconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JulianDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JulianDate&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="c1"&gt;// ...Get position from satellite-js...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cartesian3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromRadians&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;positionsOverTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we pass this &lt;code&gt;positionsOverTime&lt;/code&gt; object to our point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;satellitePoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;positionsOverTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;pixelSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cesium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RED&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point will move as the timeline at the bottom moves. To attach the camera to the moving point we do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trackedEntity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;satellitePoint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed learning a little bit about what goes into building a satellite tracker. There's a lot more to the topic we didn't touch on, like what exactly do the parameters in the TLE mean? How often are they updated? How are they updated?&lt;/p&gt;

&lt;p&gt;I don't know, but I find it really empowering to know what formats this kind of data is published in &amp;amp; where to get it, and quite amazing that we can do all this directly in the browser with JavaScript!&lt;/p&gt;

&lt;p&gt;Here's a couple fun ideas to explore now that we can do this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualize multiple satellites&lt;/strong&gt;, like the entire Starlink constellation. Inspired by &lt;a href="https://celestrak.com/cesium/orbit-viz.php?tle=/pub/TLE/catalog.txt&amp;amp;satcat=/pub/satcat.txt&amp;amp;referenceFrame=1" rel="noopener noreferrer"&gt;Celestrak's viewer&lt;/a&gt; which shows every satellite in its catalog. Perhaps visualize how the number of Starlink satellites grew over time? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Or simulate what it would look from street level&lt;/strong&gt;. Maybe add buildings/elevation data to find the best place in the city to see the satellite? &lt;/p&gt;

&lt;p&gt;There's a prototype of this in &lt;a href="https://glitch.com/edit/#!/satellite-viewer?path=street-level.html%3A1%3A0" rel="noopener noreferrer"&gt;street-level.html&lt;/a&gt; in the Glitch source code. Demo: &lt;a href="https://satellite-viewer.glitch.me/street-level.html" rel="noopener noreferrer"&gt;https://satellite-viewer.glitch.me/street-level.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1zoskrt1v9287t441wo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1zoskrt1v9287t441wo.gif" alt="satellite-street" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See also &lt;a href="https://james.darpinian.com/satellites/" rel="noopener noreferrer"&gt;James Darpinian's "See a satellite tonight"&lt;/a&gt; app which uses a combination of CesiumJS and Google street view.&lt;/p&gt;

&lt;p&gt;It might also be fun to use a 3D model of the right scale instead of a dot, and get a real sense of how close satellites get to each other in space.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>glitch</category>
      <category>tutorial</category>
    </item><item>
      <title>How to load Sketchfab models directly in a ThreeJS app</title>
      <dc:creator>Omar</dc:creator>
      <pubDate>Wed, 28 Apr 2021 01:34:15 +0000</pubDate>
      <link>https://dev.to/omar4ur/how-to-load-sketchfab-models-directly-in-a-threejs-app-5anb</link>
      <guid>https://dev.to/omar4ur/how-to-load-sketchfab-models-directly-in-a-threejs-app-5anb</guid>
      <description>&lt;p&gt;&lt;a href="https://sketchfab.com/" rel="noopener noreferrer"&gt;Sketchfab's&lt;/a&gt; API gives you programmatic access to the largest collection of glTF 3D models on the web. This article walks you through a minimal code example to show you how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let your users authenticate with the Sketchfab API&lt;/li&gt;
&lt;li&gt;Download a 3D model as a zip file containing the glTF&lt;/li&gt;
&lt;li&gt;Load this zip file into ThreeJS&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Source code: &lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example" rel="noopener noreferrer"&gt;https://github.com/OmarShehata/threejs-sketchfab-example&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;I originally implemented this to let readers of my &lt;a href="https://omar-shehata.medium.com/how-to-render-outlines-in-webgl-8253c14724f9" rel="noopener noreferrer"&gt;WebGL outlines &lt;/a&gt; tutorial see how the effect looked on test cases of their choosing. Since I kept finding algorithms that didn't work on my specific corner cases (but I wouldn't find out until after I implemented it/downloaded &amp;amp; ran it!)&lt;/p&gt;

&lt;p&gt;It's a really easy way to let users bring in their own data (or millions of example models).&lt;/p&gt;

&lt;p&gt;You can see how this works in this outlines live demo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the demo: &lt;a href="https://omarshehata.github.io/csb-l01dp/" rel="noopener noreferrer"&gt;https://omarshehata.github.io/csb-l01dp/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click Login to &lt;strong&gt;Sketchfab&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;When directed back to the app, paste a link of a model in the &lt;strong&gt;Sketchfab URL&lt;/strong&gt; field, like this: &lt;a href="https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393" rel="noopener noreferrer"&gt;https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ldinswfyw845o36hzn8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ldinswfyw845o36hzn8.gif" alt="load-example" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The model must be downloadable by the Sketchfab account that's logged in.&lt;/p&gt;

&lt;h3&gt;
  
  
  1 - Authenticate with the Sketchfab API
&lt;/h3&gt;

&lt;p&gt;The first step is to register your app with Sketchfab. The instructions for this are here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sketchfab.com/developers/oauth#registering-your-app" rel="noopener noreferrer"&gt;https://sketchfab.com/developers/oauth#registering-your-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The current process at the time of writing is to contact them.&lt;/p&gt;

&lt;p&gt;You'll need to pick a &lt;strong&gt;redirect URI&lt;/strong&gt;. This should be the final URI where you will deploy your app. &lt;/p&gt;

&lt;p&gt;You'll want to use the &lt;strong&gt;Implicit&lt;/strong&gt; grant type. We can't keep an API key a secret in a web app, so we instead rely on the redirect URI (if someone malicious uses your client ID, Sketchfab will redirect them to your real app after login, regardless of who may have initiated the login).&lt;/p&gt;

&lt;p&gt;After your register your app you'll have a Client ID.&lt;br&gt;
You'll use this to send the user to Sketchfab for login as shown here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CLIENT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_CLIENT_ID_HERE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AUTHENTICATION_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://sketchfab.com/oauth2/authorize/?state=123456789&amp;amp;response_type=token&amp;amp;client_id=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTHENTICATION_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the login is done, you'll need to &lt;strong&gt;grab the access token from the URL&lt;/strong&gt;. Here's a snippet that does this and stores it in local storage here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;checkToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Check if there's a new token from the URL&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Extract the token and save it&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;param&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;hashParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;access_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#access_token=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Detected Sketchfab token: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sb_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Load token from local storage&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sb_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L77-L92" rel="noopener noreferrer"&gt;Source code on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You'll use this token for subsequent API calls.&lt;/p&gt;

&lt;p&gt;Note: while you're developing locally, Sketchfab will redirect to the production URI. You'll need to copy the URI params to your localhost to test.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 - Download the 3D model
&lt;/h3&gt;

&lt;p&gt;Once you have a token, you can use this to fetch a download URI for the glTF model.&lt;/p&gt;

&lt;p&gt;Here is the code snippet for fetching the download URI given any Sketchfab URI like this: &lt;a href="https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393" rel="noopener noreferrer"&gt;https://sketchfab.com/3d-models/skull-downloadable-1a9db900738d44298b0bc59f68123393&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getModelDownloadUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Extract the model ID from the URL&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// The ID is always the last string when seperating by '-'&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pieces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modelID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pieces&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pieces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;metadataUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.sketchfab.com/v3/models/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;modelID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/download`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// This call will fail if model can't be downloaded&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metadataUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L95-L115" rel="noopener noreferrer"&gt;Source code on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that this request will fail if the user who is logged in does not have access to download this model. This will be true for store models that require a purchase, or free models that are not downloadable.&lt;/p&gt;

&lt;p&gt;You can filter for downloadable models in the Sketchfab search:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lxaey2riyt888ap10u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lxaey2riyt888ap10u1.png" alt="firefox_EH3grorHBC" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will show you either free models you can download or models that can be purchased.&lt;/p&gt;

&lt;p&gt;Now that we have a URL to a zip file containing a glTF model, we can pass that to ThreeJS to load it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3 - Load the ZIP file into ThreeJS
&lt;/h3&gt;

&lt;p&gt;This was the tricky part of me. Normally ThreeJS requires a direct URL to the glTF file. To load it from a zip file we're going to (1) unzip the contents into memory using JSZip.&lt;/p&gt;

&lt;p&gt;We can't just pass the unzipped raw content to ThreeJS, because a glTF file may reference other files by a filepath (image or geometry resources). So we need to (2) create a Blob for each resource and (3) override the resources the glTF file is requesting with the Blob URI's.&lt;/p&gt;

&lt;p&gt;For example, if the glTF file is trying to load &lt;code&gt;textures/defaultMat_baseColor.jpeg&lt;/code&gt; as a relative filepath, we detect this, and instead pass this URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Unzip from JSZip&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unzippedBaseColorJPEGFile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Create a Blob from this file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Create a URL to this Blob&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseColorBlobUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Use ThreeJS's loading manager so instead of loading from relative filepaths we load from the blob URI's we created&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadingManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LoadingManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                            &lt;span class="nx"&gt;loadingManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setURLModifier&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textures/defaultMat_baseColor.jpeg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;baseColorBlobUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;a href="https://threejs.org/docs/#api/en/loaders/managers/LoadingManager" rel="noopener noreferrer"&gt;ThreeJS's LoadingManager&lt;/a&gt; to do this.&lt;/p&gt;

&lt;p&gt;Here is the code snippet that can take a URL to any zipped glTF and load it in ThreeJS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;readZip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zipUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zipUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;checkStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;JSZip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entryFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gltf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Create blobs for every file resource&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blobUrls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Loading &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;blobUrls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getFileUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blobUrls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entryFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Re-add the light&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;light&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DirectionalLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;light&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadingManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LoadingManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;loadingManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setURLModifier&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsedUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parsedUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parsedUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;relativeUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blobUrls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;relativeUrl&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;blobUrls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;relativeUrl&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gltfLoader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GLTFLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loadingManager&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;gltfLoader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/b780b8c1eac37fc71d8d803fc465c874efd5954c/SketchfabIntegration.js#L30-L70" rel="noopener noreferrer"&gt;Source code on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4 - Display attribution
&lt;/h3&gt;

&lt;p&gt;Using 3D models from Sketchfab in your application requires that you display attribution to the original author. &lt;a href="https://help.sketchfab.com/hc/en-us/articles/360038413232-Crediting-users-for-3D-model-downloads" rel="noopener noreferrer"&gt;Read more about this on Sketchfab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can automatically get the attribution &amp;amp; license information from this &lt;a href="https://docs.sketchfab.com/data-api/v3/index.html#!/models/get_v3_models_uid" rel="noopener noreferrer"&gt;Data API route&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a function that will construct the attribution text given a modelID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getAttributionText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modelDataUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.sketchfab.com/v3/models/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;modelID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelDataUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileUrl&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;viewerUrl&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;attributionText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
        &lt;span class="s2"&gt;`This work is based on &amp;lt;a href="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" target=_blank&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;
        by &amp;lt;a href="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" target=_blank&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt; 
        licensed under &amp;lt;a href="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" target=_blank&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;attributionText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/OmarShehata/threejs-sketchfab-example/blob/8d126d00faf47fb0b99f9f2f7c78a25332ccfb7b/SketchfabIntegration.js#L121-L142" rel="noopener noreferrer"&gt;Source code on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The example app will display the attribution in the bottom left corner, linking to the original model URL, author's Sketchfab profile, and the license.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrzgtob2ov68ji2ytk1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrzgtob2ov68ji2ytk1s.png" alt="firefox_1AiYv9o6O5" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Known issues
&lt;/h3&gt;

&lt;p&gt;One problem with loading some Sketchfab models is that their scale will be much bigger than the current viewport. Another problem is some models may not be centered around the origin, so they may not be visible when loaded.&lt;/p&gt;

&lt;p&gt;Normalizing and scaling models when loading them in ThreeJS would help solve this, similar to how &lt;a href="https://gltf-viewer.donmccurdy.com/" rel="noopener noreferrer"&gt;Don McCurdy's glTF Viewer&lt;/a&gt; works.&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you found this helpful, follow me on Twitter &lt;a class="mentioned-user" href="https://dev.to/omar4ur"&gt;@omar4ur&lt;/a&gt; to see more of my work. Other ways to reach me at &lt;a href="https://omarshehata.me/" rel="noopener noreferrer"&gt;https://omarshehata.me/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>threejs</category>
      <category>javascript</category>
      <category>gltf</category>
      <category>3d</category>
    </item><item><title>How to hire a lawyer in the court of public opinion</title><description>Last Monday I announced that I have been running a company, now with a bit of formal paperwork, and it&amp;#8217;s called &amp;#8220;Prosocial Engineering&amp;#8221;.</description><link>https://omarshehata.substack.com/p/how-to-hire-a-lawyer-in-the-court</link><guid isPermaLink="false">https://omarshehata.substack.com/p/how-to-hire-a-lawyer-in-the-court</guid><dc:creator>omar</dc:creator><pubDate>Mon, 30 Mar 2026 16:24:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PDkT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;Last &lt;a href="https://omarshehata.substack.com/p/starting-a-company-devlog"&gt;Monday I announced&lt;/a&gt; that I have been running a company, now with a bit of formal paperwork, and it&amp;#8217;s called &amp;#8220;Prosocial Engineering&amp;#8221;. &lt;/p&gt;&lt;p&gt;The only &amp;#8220;formal paperwork&amp;#8221; I have so far is a DBA, filed on Feb 26th 2026. This means my business is just me, a sole proprietor. If I need to declare bankruptcy then my personal assets are at risk. But this is enough to get me started - when I need to take on greater risk I plan to do it in partnership with other orgs in my network who have offered to act as a &amp;#8220;fiscal host&amp;#8221; for my projects, like &lt;a href="https://analoguegroup.org/"&gt;Analogue&lt;/a&gt;, Jonah from &lt;a href="https://innovationlens.org/"&gt;Innovation Lens&lt;/a&gt;, and for local Ithaca projects, &lt;a href="https://centerfortransformativeaction.org/"&gt;CTA&lt;/a&gt;, &lt;a href="https://weavecommunity.org/the-soil-factory-2/"&gt;Weave&lt;/a&gt;, or &lt;a href="https://www.nyrhi.org/"&gt;NY RHI&lt;/a&gt;&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self"&gt;1&lt;/a&gt;.   &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PDkT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PDkT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 424w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 848w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 1272w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!PDkT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png" width="422" height="213.97946084724006" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:395,&amp;quot;width&amp;quot;:779,&amp;quot;resizeWidth&amp;quot;:422,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:&amp;quot;Image&amp;quot;,&amp;quot;title&amp;quot;:&amp;quot;Image&amp;quot;,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!PDkT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 424w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 848w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 1272w, https://substackcdn.com/image/fetch/$s_!PDkT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b44e7bd-b072-4dcb-86e0-30259bcf0061_779x395.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In last week&amp;#8217;s post &lt;span class="mention-wrap" data-attrs="{&amp;quot;name&amp;quot;:&amp;quot;Ralph&amp;quot;,&amp;quot;id&amp;quot;:2093813,&amp;quot;type&amp;quot;:&amp;quot;user&amp;quot;,&amp;quot;url&amp;quot;:null,&amp;quot;photo_url&amp;quot;:&amp;quot;https://substackcdn.com/image/fetch/$s_!IJTe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fedaa6592-3fb5-40a3-a7be-7a4dab30ba5b_96x96.jpeg&amp;quot;,&amp;quot;uuid&amp;quot;:&amp;quot;978ff6ea-fa94-48a7-ae57-89959cb30edf&amp;quot;}" data-component-name="MentionToDOM"&gt;&lt;/span&gt; &amp;amp; &lt;span class="mention-wrap" data-attrs="{&amp;quot;name&amp;quot;:&amp;quot;Joshua Hutt&amp;quot;,&amp;quot;id&amp;quot;:208039503,&amp;quot;type&amp;quot;:&amp;quot;user&amp;quot;,&amp;quot;url&amp;quot;:null,&amp;quot;photo_url&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/833d7f8b-02e0-43d2-a727-e6ae89d3e0e8_460x460.jpeg&amp;quot;,&amp;quot;uuid&amp;quot;:&amp;quot;19c0e317-b974-4dfe-8d79-8d78fff71303&amp;quot;}" data-component-name="MentionToDOM"&gt;&lt;/span&gt; both asked, essentially:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I&amp;#8217;m sorry what does your business actually do&amp;#8230;? Who&amp;#8217;s paying you, for what here?&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self"&gt;2&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;So, let me to try to answer that today.&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;I am in the business of providing a service of &amp;#8220;lawyer in the court of public opinion&amp;#8221;. &lt;/p&gt;&lt;p&gt;There is a large industry of many companies that do this. We operate in the same market as those companies. &lt;/p&gt;&lt;p&gt;In &lt;a href="https://defenderofthebasic.substack.com/p/new-york-times-is-trying-to-explain"&gt;Jan 2025 the New York Times documented&lt;/a&gt; one such company. The standard in this industry is secrecy. The services these companies provide are NOT publicly listed anywhere. Typically you hire them &amp;amp; they perform the service and no one knows that you hired them. Otherwise they fail to deliver the service.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;They hired a digital contractor who offers crisis management services. His name is Jed Wallace, and there&amp;#8217;s actually very little trace of him online, but in a deleted LinkedIn profile, he described himself as a &amp;#8220;hired gun&amp;#8221;, with a proprietary formula for defining artists and trends&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;em&gt;from: &lt;a href="https://www.nytimes.com/2025/01/28/podcasts/the-daily/blake-lively-justin-baldoni-it-ends-with-us.html"&gt;&amp;#8220;The Legal Battle Riveting Hollywood&amp;#8221;&lt;/a&gt; NYT The Daily Podcast&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I do the same thing, except I do it transparently. You cannot hire me without everyone knowing that you hired me. &lt;/p&gt;&lt;p&gt;If you want to hire one of these guys, you have to go through &amp;#8220;dark alleys&amp;#8221; of whisper networks. If you want to hire me, you see a big billboard, call the number, go through the front door. &lt;/p&gt;&lt;p&gt;If you pay one of these guys, and they defraud you/don&amp;#8217;t deliver anything, you don&amp;#8217;t have much recourse (unregulated dark web). If you pay me and you are unhappy with the service, it will hurt my public reputation. And you can also sue me. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Ok, but what exactly does a &amp;#8220;lawyer in the court of public opinion&amp;#8221; do?&lt;br&gt;&lt;strong&gt;A:&lt;/strong&gt; He does the same thing that a lawyer does in a real court, but in the court of public opinion. &lt;/p&gt;&lt;p&gt;The easiest way to explain this to someone like my mom is: it&amp;#8217;s just a marketing company. But it&amp;#8217;s an honest one&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self"&gt;3&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;For you guys, I&amp;#8217;ll say: it is as I explained in the last post, I get paid to change minds towards the truth. We do R&amp;amp;D on projects that help improve truth seeking &lt;em&gt;in general, &lt;/em&gt;but we also (now) take on specific projects, like changing people&amp;#8217;s minds about a specific company, product, or research paradigm. &lt;/p&gt;&lt;p&gt;Honestly half the work is just monitoring communities that have high epistemic rigor &amp;amp; integrity&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self"&gt;4&lt;/a&gt;. If you want the answer, go see what they&amp;#8217;re saying. If you are struggling to make sense of what they&amp;#8217;re saying, or if no one there has reviewed the thing you need reviewed, we have a &amp;#8220;guy on the inside&amp;#8221; who can ask that question, ideally in public so that everyone learns the answer. You pay to fund the work, but the answers benefit everyone. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Q: &lt;/strong&gt;Do you have a concrete example?&lt;br&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes! I will give you 2 examples.&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/SASenchal/God-Conjecture?tab=readme-ov-file#god-conjecture"&gt;Sam Senchal&lt;/a&gt; is one of my clients where we delivered a successful project together. He is not an academic, does not have a PhD or anything, but he had some ideas about how to contribute to academic research. &lt;/p&gt;&lt;p&gt;His work is now endorsed/publicly reviewed by Stephen Wolfram, Michael Levin, a few other notable academics, and the most recent milestone was getting an opportunity to pitch a research proposal to a frontier AI lab. &lt;/p&gt;&lt;p&gt;To be honest, I didn&amp;#8217;t do that much for Sam. He already had a really valuable insight, mostly all I did was say &lt;em&gt;&amp;#8220;I think this will be an A&lt;/em&gt;&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self"&gt;5&lt;/a&gt;&lt;em&gt; for people in this community, and that community. Try posting it there and see what happens&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;My relationship to Sam has oscillated between me performing work for him, and him performing work for me (I help him with his research outreach &amp;amp; gathering feedback, and he helps me with other clients I have whose work may be valuable, he opens doors for them by endorsing/reviewing their work). I&amp;#8217;m not sure yet who should be paying who here - this is part of what I meant when I said &amp;#8220;money&amp;#8221; is my primary focus right now, I&amp;#8217;m trying to figure out how to price the services and set the expectations of what we do. &lt;/p&gt;&lt;p&gt;The second example is &lt;a href="https://omarshehata.substack.com/p/twitter-shut-off-api-access-users"&gt;Twitter Community Archive&lt;/a&gt;&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self"&gt;6&lt;/a&gt;, which is a project that I did, among other things, a lot of the early marketing for. This one was REALLY fun because the job was basically &amp;#8220;who do we call to launch a research lab, in a field that doesn&amp;#8217;t exist yet?&amp;#8221; - so the work performed here was two part (1) do public advocacy to explain what kinds of research questions are worth asking and funding (2) help a specific company get the attention it needs to deliver on that. The company that was formed that delivered on this is called &lt;a href="https://www.epistemic.garden/"&gt;Epistemic Garden&lt;/a&gt;. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;What&amp;#8217;s coming up next?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&amp;#8220;ORI&amp;#8221; is taking a lot of my attention. &amp;#8220;ORI&amp;#8221; is one of the projects maintained by Prosocial Engineering, it&amp;#8217;s what helped Sam find the communities he needed to find to publish &amp;amp; get noticed. I am thinking of a way to create a monetization path here. My best idea is to write the onboarding guide, make it free, but ask people to pay to buy it as a physical book/zine, and to support the project&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I want to focus on &amp;#8220;Anatomy of an Internet Argument&amp;#8221;. It is the strongest brand I have, and it does have a clear monetization path. I spend a lot of time supporting others projects, and this one is my own, and I think I need to prioritize it. In a kind of &amp;#8220;help yourself before you can help others&amp;#8221; kind of way&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I think asking for &amp;amp; receiving money has been something I&amp;#8217;ve been uncomfortable about - but now I am starting to see it as a way to help myself align the incentives. cc &lt;a href="https://rosano.ca/"&gt;Rosano&lt;/a&gt;&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-7" href="#footnote-7" target="_self"&gt;7&lt;/a&gt;. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PbWa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PbWa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 424w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 848w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!PbWa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg" width="478" height="500.7202925045704" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1146,&amp;quot;width&amp;quot;:1094,&amp;quot;resizeWidth&amp;quot;:478,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:&amp;quot;Image&amp;quot;,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!PbWa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 424w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 848w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!PbWa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbb081-5cd8-4798-b66b-c17619d72554_1094x1146.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;Recent conversation in the ORI discord about monetizing projects and how to do that without corrupting the work &lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self"&gt;1&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;In case you haven&amp;#8217;t noticed, I REALLY don&amp;#8217;t want to run my own business. This is part of why it has taken me so long to make this announcement. I was hoping to be hired/absorbed by a larger org who can benefit from my work &amp;amp; capture the value I am creating, which is how I&amp;#8217;m used to working. At my first startup, Cesium, I did a lot of work and it was someone else&amp;#8217;s job to hire/fire/negotiate contracts/set the company direction. At Snapchat I did a lot of work, including a lot of experimental, very cool &amp;amp; interesting deep work that did not directly make money, but could be funded by other parts of the org that generate revenue. &lt;/p&gt;&lt;p&gt;So what I&amp;#8217;m doing is seeing if I can &amp;#8220;find the pieces&amp;#8221; I need through collaborators and partnerships with other orgs. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self"&gt;2&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;Stripe also asked me this, &lt;em&gt;[Action required] Provide information about what you sell&lt;/em&gt; - so, that&amp;#8217;s why I&amp;#8217;m working on this today. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self"&gt;3&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;&amp;#8220;but don&amp;#8217;t they all say that&amp;#8221; &amp;#8594; yes, but they cannot prove it. You can ask them to prove it. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self"&gt;4&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;My sources have primarily been the &amp;#8220;rationalists&amp;#8221; (https://www.lesswrong.com/about), a panel of academic friends &amp;amp; volunteers, primarily at Cornell, and friends and family in the tech industry. The rationalists are a high signal source of information, but they do have blindspots, and those are easy to see when you ask the same question to multiple disconnected networks, like comparing Cornell vs rationalists. &lt;/p&gt;&lt;p&gt;Growing this list, and maintaining active connections is a core part of the day to day work. Ideally we have &amp;#8220;read-write&amp;#8221; permission in these networks. Like we don&amp;#8217;t just passively observe, but we can ask questions, or propagate information that may be good &amp;amp; useful for these networks.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-5" href="#footnote-anchor-5" class="footnote-number" contenteditable="false" target="_self"&gt;5&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;An &amp;#8220;A&amp;#8221; rating refers to the A/B/U system, which acts as a basic taxonomy of ideas. See a layperson explanation in &lt;a href="https://omarshehata.substack.com/p/how-we-grade-presentation-night"&gt;&amp;#8220;How we grade presentation night&amp;#8221;&lt;/a&gt; and the more technical explanation here: &lt;a href="https://openresearchinstitute.org/onboarding/A_B_U.html"&gt;https://openresearchinstitute.org/onboarding/A_B_U.html&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-6" href="#footnote-anchor-6" class="footnote-number" contenteditable="false" target="_self"&gt;6&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;Examples of concrete things I did here was (1) get the project on the &lt;a href="https://news.ycombinator.com/item?id=41581923"&gt;frontpage of HackerNews&lt;/a&gt; (2) get &lt;a href="https://www.kalzumeus.com/"&gt;Patrick McKenzie&lt;/a&gt;, notable name in tech to join and endorse the project (3) get &lt;a href="https://www.etymologynerd.com/"&gt;Etymology Nerd&lt;/a&gt;, a big youtuber to feature the project, specifically the &amp;#8220;psyop vs vibe&amp;#8221; word origin graph. &lt;/p&gt;&lt;p&gt;I want to disclose this to HackerNews at some point - that I know how to get things on the front page, and I practice this as regularly as I can. When they see a post from me they should know &amp;#8220;it is targeted&amp;#8221;. But the game I play is that, I need a feedback loop. I try to put things on HN that people of HN will find &amp;#8220;true &amp;amp; useful&amp;#8221; (A). If I fail to do that, that means I picked a bad project/idea, and should be penalized for that. The information ecosystem gets better if we reward sources of high signal information, and punish sources of low quality information (regardless of your intention)&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-7" href="#footnote-anchor-7" class="footnote-number" contenteditable="false" target="_self"&gt;7&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;I&amp;#8217;ve been thinking about my conversations with Rosano on this - about how to fund people who are doing good work, especially because many of them are not marketing themselves, are ironically hard to find even when you DO have money and want to fund them&lt;/p&gt;&lt;p&gt;I have been enjoying using this carrot image as a symbol of &amp;#8220;the problem&amp;#8221; that I am working on solving, permanently (not as another iteration of the cat &amp;amp; mouse game)&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kVNB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kVNB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!kVNB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg" width="298" height="291.0466666666667" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/f9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:293,&amp;quot;width&amp;quot;:300,&amp;quot;resizeWidth&amp;quot;:298,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:&amp;quot;Image&amp;quot;,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!kVNB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kVNB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9c75466-3a43-4594-8854-43c30985ca46_300x293.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;That&amp;#8217;s really the biggest claim I have - that it is possible to permanently solve this signaling problem (where projects that receive money are the loudest, not the ones with substance). &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</ns2:encoded></item><item><title>Starting a company - devlog </title><description>Good morning!</description><link>https://omarshehata.substack.com/p/starting-a-company-devlog</link><guid isPermaLink="false">https://omarshehata.substack.com/p/starting-a-company-devlog</guid><dc:creator>omar</dc:creator><pubDate>Mon, 23 Mar 2026 16:19:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gVwC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;Good morning! Today is day 1 of me formally starting a company. &lt;/p&gt;&lt;p&gt;Technically I&amp;#8217;ve been running this business &lt;a href="https://omarshehata.me/notebook/office_snapshot"&gt;since June 2024&lt;/a&gt; when I quit my dayjob at Snapchat, but it&amp;#8217;s been &amp;#8220;in stealth&amp;#8221; thus far&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self"&gt;1&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;It&amp;#8217;s called Prosocial Engineering. As in, professional social engineering. And also, &lt;em&gt;prosocial&lt;/em&gt; social engineering. Its logo is one of the memes that originated in our lab - the yellow hat&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self"&gt;2&lt;/a&gt;. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gVwC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gVwC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 424w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 848w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 1272w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!gVwC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp" width="548" height="303" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/f11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:303,&amp;quot;width&amp;quot;:548,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:&amp;quot;Image&amp;quot;,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!gVwC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 424w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 848w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 1272w, https://substackcdn.com/image/fetch/$s_!gVwC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff11ab592-7032-40f2-8f93-9e59340426b2_548x303.webp 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;It&amp;#8217;s an open source marketing company&lt;/strong&gt;. I take in clients who want to change minds for a purpose. This can be of large group of minds, like marketing a product to consumers in a specific cohort, or a small group of minds, like specific investors, philanthropists, or other kinds of individual gatekeepers. &lt;/p&gt;&lt;p&gt;&amp;#8220;open source&amp;#8221; is the unique part. We have very effective methods for changing people&amp;#8217;s minds - but we ALWAYS announce it first, and fully document it &amp;amp; post mortem it. This guarantees that our work is always &amp;#8220;good&amp;#8221; - if the marketing campaign works, BUT the subject becomes aware it is a marketing campaign, and is upset &amp;amp; changes their mind back, that&amp;#8217;s GOOD. This is the safety &amp;#8220;eject&amp;#8221; button that the receiver is allowed to push for any reason, at any time. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;A positive side effect of running this business is cleaning up the information environment in any of the territories we operate in, &lt;em&gt;&amp;#8220;raising the epistemic waterline&amp;#8221;&lt;/em&gt;. Before we can effectively propagate information, we begin first by doing a &amp;#8220;full sweep&amp;#8221; of the network. This involves:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;(1) taking a snapshot of all current beliefs, and &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;(2) observing the process of belief change (where does the change originate, how does it propagate through the network, how does it reach full saturation, what defense mechanisms are present, if any)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Once this process is complete, healthy information propagation becomes very easy across the entire network &lt;em&gt;(buying, selling, recruiting, collective sense making, match making). &lt;/em&gt;This process fails if there are already other agencies operating on the network, and may be hostile to attempts to &amp;#8220;clean up&amp;#8221;. &lt;/p&gt;&lt;p&gt;Here is how one member described it poetically:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pQ6v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pQ6v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 424w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 848w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 1272w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!pQ6v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png" width="524" height="476.43692307692305" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1182,&amp;quot;width&amp;quot;:1300,&amp;quot;resizeWidth&amp;quot;:524,&amp;quot;bytes&amp;quot;:300850,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/191855242?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pQ6v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 424w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 848w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 1272w, https://substackcdn.com/image/fetch/$s_!pQ6v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F619f6b65-f48e-4f63-8ba9-2949affd1dbb_1300x1182.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://x.com/DefenderOfBasic/status/2022014275678875774"&gt;x.com/DefenderOfBasic/status/2022014275678875774&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;See v1 of the website here: &lt;a href="https://prosocialengineering.org/"&gt;https://prosocialengineering.org/&lt;/a&gt;. My immediate goal is: money. There are a lot of projects that are ready to launch that are sitting on deck that I would like to fundraise for. We also have a lot of services that we can offer that I&amp;#8217;m looking for paying clients for. &lt;/p&gt;&lt;p&gt;Rough roadmap of the next few months:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Launch &lt;a href="https://defenderofthebasic.substack.com/p/anatomy-of-an-internet-argument"&gt;Anatomy of an Internet Argument&lt;/a&gt;, do weekly case studies, grow a community around it &amp;amp; monetize the artifacts&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self"&gt;3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Teach everyone how to setup their own &amp;#8220;open culture science base station&amp;#8221;, and how to connect your instance to the global network of cultural ambassadors&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self"&gt;4&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Perform a &amp;#8220;mic check&amp;#8221; across the full network. This is like putting in a material in a human body that shows up in CAT scans so you can look for blockages, but for our information networks/collective language&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self"&gt;5&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I think this is the general direction of the business. The marketing work can be paid for directly by companies that want it. The research work can be funded either by philanthropy/grants, or by those same companies (&lt;em&gt;a failed marketing campaign doubles as a successful research experiment we can publish, if it surfaces why people did not like thing/what the origin of the resistance was).&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Some of our work inside specific territories may grow big enough to become its own thing. For example, at some point we shifted focus to operate on the culture of peer review &amp;amp; science communication, the result of that was the creation of the brand &lt;a href="https://openresearchinstitute.org/"&gt;&amp;#8220;ORI - Open Research Institute&amp;#8221;&lt;/a&gt;. This is currently still running as a project/experiment by Prosocial Engineering, but may spin out one day.&lt;/p&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self"&gt;1&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;&amp;#8220;Stealth&amp;#8221; is in quotes because, technically, every single step of the way from the very beginning has been publicly documented. And yet, I&amp;#8217;ve managed to maintain a lot of secrets from a lot of parties on a &amp;#8220;need to know&amp;#8221; basis. This is great because, as I hope you&amp;#8217;ll understand from this post, we&amp;#8217;re in the business of information management, and this gives me confidence that our open-source methods work, despite the constraint of full transparency. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self"&gt;2&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;A &lt;a href="https://x.com/defenderofbasic/"&gt;popular &amp;#8220;influencer&amp;#8221;/contributor&lt;/a&gt; in the network wears a yellow hat in their profile picture - but several others wear it as well, online and in real life. This &lt;a href="https://en.wikipedia.org/wiki/Function_overloading"&gt;&amp;#8220;overloading&amp;#8221;&lt;/a&gt; of meaning ontop of an existing symbol is a well known technique for hiding in plain sight. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self"&gt;3&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;This is essentially an internet wide game to study &amp;amp; influence subcultures, with full awareness &amp;amp; proper guardrails. It tilts the playing field from the average hostile internet interaction to wholesome, productive, and positive sum. At worst you learn about people you consider your enemies, at best you &amp;#8220;convert&amp;#8221; others and propagate what is good &amp;amp; true. It turns &amp;#8220;culture war&amp;#8221; into &amp;#8220;culture science&amp;#8221; and acts as a way for us to recruit cultural ambassadors in every corner of the internet.  &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self"&gt;4&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;This is essentially teaching every community how A/B testing works, and connecting them with at least ONE other disconnected network on earth, so they can perform A/B testing from wherever they stand. This is the best defense against unwanted surveillance - to be able to see your culture &amp;#8220;from the inside&amp;#8221; and from one or more trusted vantage points &amp;#8220;from the outside&amp;#8221;. Together they form a complete picture of your information network. &lt;/p&gt;&lt;p&gt;Most humans only exist in one isolated network and so cannot perform any kind of triangulation to trace the origin of changes to their language/culture/memome. &lt;/p&gt;&lt;p&gt;This will also involve writing down all the work, research, and insights we got from all of our experiments in 2025. We&amp;#8217;ve only written one of these case studies, see &lt;a href="https://defenderofthebasic.substack.com/p/my-first-open-source-psyop-postmortem"&gt;&amp;#8220;my first open source psyop with etymologynerd&amp;#8221;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-5" href="#footnote-anchor-5" class="footnote-number" contenteditable="false" target="_self"&gt;5&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;The trick here is to find a payload that&amp;#8217;s worth propagating. These mic checks are &amp;#8220;very noisy&amp;#8221; &amp;amp; easily abused, unless they surface information that is useful for everyone.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</ns2:encoded></item><item><title>How we grade presentation night </title><description>Presentation Night is a ~monthly event I host here in Ithaca.</description><link>https://omarshehata.substack.com/p/how-we-grade-presentation-night</link><guid isPermaLink="false">https://omarshehata.substack.com/p/how-we-grade-presentation-night</guid><dc:creator>omar</dc:creator><pubDate>Thu, 18 Dec 2025 16:01:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vr2l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;&lt;a href="https://omarshehata.substack.com/p/presentation-night-feb-7-recap"&gt;Presentation Night&lt;/a&gt; is a ~monthly event I host here in Ithaca. It&amp;#8217;s a series of 5 minute talks &amp;#8212; I often describe it as an &lt;em&gt;&amp;#8220;open mic, but with slides&amp;#8221;&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;At yesterday&amp;#8217;s event I gave a little keynote about what makes a GOOD pres night talk. It&amp;#8217;s something I&amp;#8217;ve been thinking about for 2 years now, and I think I finally got it. &lt;/p&gt;&lt;p&gt;I introduced this &amp;#8220;grading scheme&amp;#8221;: A, B, or U. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vr2l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vr2l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 424w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 848w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 1272w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!vr2l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png" width="532" height="344.98039215686276" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/cdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:926,&amp;quot;width&amp;quot;:1428,&amp;quot;resizeWidth&amp;quot;:532,&amp;quot;bytes&amp;quot;:96574,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vr2l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 424w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 848w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 1272w, https://substackcdn.com/image/fetch/$s_!vr2l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdad4b07-60ad-42b0-806f-b34adc5a64a1_1428x926.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;The purpose of presentation night is for the speakers to come with THEIR A&amp;#8217;s. Things that they have recently learned. &lt;/p&gt;&lt;p&gt;The audience then receives this either as A, B, or U. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&amp;#9989; It&amp;#8217;s good if most of the audience receives it as an A, you taught them something new!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&amp;#9989; It&amp;#8217;s also good if most receive it as a B - that means they recognize the thing you&amp;#8217;re talking about as true &amp;amp; useful. You did a good job explaining it!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&amp;#8265;&amp;#65039; U is not bad, it&amp;#8217;s &amp;#8220;unknown&amp;#8221;. They didn&amp;#8217;t pick it up, but we don&amp;#8217;t know why&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is designed to be a NON HIERARCHICAL system - each of these categories surfaces feedback that is useful to both sides. &lt;/p&gt;&lt;p&gt;The &amp;#8220;U&amp;#8221; in this language is often &amp;#8220;silent&amp;#8221; (if no one says anything / asks questions, we take that to be a U) &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;Here were the two examples I gave for how this system works. &lt;/p&gt;&lt;h4&gt;(1) &lt;/h4&gt;&lt;p&gt;At a previous pres night, Laura Colket explained something she recently learned about how humans learn: that the idea that people have &amp;#8220;individual learning styles&amp;#8221; is a myth&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self"&gt;1&lt;/a&gt;&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Kgr-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Kgr-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 424w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 848w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 1272w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Kgr-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png" width="466" height="245.8021978021978" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:768,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:466,&amp;quot;bytes&amp;quot;:142877,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Kgr-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 424w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 848w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 1272w, https://substackcdn.com/image/fetch/$s_!Kgr-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32bfdf95-2ce9-4f0e-93a3-87914ae04409_2188x1154.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LPpu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LPpu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 424w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 848w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 1272w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!LPpu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png" width="456" height="341.06043956043953" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/e8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1089,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:456,&amp;quot;bytes&amp;quot;:2518428,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LPpu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 424w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 848w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 1272w, https://substackcdn.com/image/fetch/$s_!LPpu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e9fecf-00d7-4885-b152-aaffa47984dc_1482x1108.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I then showed what I think the audience reaction was to Laura&amp;#8217;s talk. In the figure below:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;she is the speaker in the top hat presenting her A&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6UBC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6UBC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 424w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 848w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 1272w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!6UBC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png" width="480" height="327.3626373626374" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:993,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:480,&amp;quot;bytes&amp;quot;:297616,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6UBC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 424w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 848w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 1272w, https://substackcdn.com/image/fetch/$s_!6UBC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2b0c3d9c-1a0b-4478-8a67-463c0d03cfa9_1634x1114.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;this was a new concept, A, for a bunch of people &lt;em&gt;(blew one guy&amp;#8217;s mind in the back of the room)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;it was a B for a few folks - you could tell because they were BUILDING on top of it. They made comments like &amp;#8220;there&amp;#8217;s a book that explains this really well&amp;#8221; or &amp;#8220;if you&amp;#8217;re this kind of learner, you can test it in this way or that way, it really worked for me&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It was a U for a couple folks - maybe because they weren&amp;#8217;t paying attention, or it was going too fast for them. OR that it just didn&amp;#8217;t seem true in THEIR experience - maybe they tried combining learning modes and it made things worse for them?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;(2) &lt;/h4&gt;&lt;p&gt;The second example was a more spicy one, and it&amp;#8217;s a case where a speaker presents something that is an A for them&amp;#8230;but is not actually true. What happens in that case?&lt;/p&gt;&lt;p&gt;That presentation was about the &amp;#8220;aether&amp;#8221; - the idea that reality is not made out of atoms, but some medium that we&amp;#8217;re all swimming in, and atoms are just &amp;#8220;clumps&amp;#8221; in that medium.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0oEK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0oEK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!0oEK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png" width="462" height="283.03846153846155" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/ecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:892,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:462,&amp;quot;bytes&amp;quot;:83907,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0oEK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0oEK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecfb97b8-31ff-4dff-9399-159b35e92f44_1672x1024.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Here is my visual illustration of the audience&amp;#8217;s reaction to Trevor&amp;#8217;s talk on this:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hl-x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hl-x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 424w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 848w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 1272w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Hl-x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png" width="500" height="346.15384615384613" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1008,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:500,&amp;quot;bytes&amp;quot;:300140,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Hl-x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 424w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 848w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 1272w, https://substackcdn.com/image/fetch/$s_!Hl-x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e11b468-f4c6-4451-8e76-02ea039af34a_1678x1162.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Most people received it as a U. A few people received it as an A. &lt;/p&gt;&lt;p&gt;Trevor may have had more A&amp;#8217;s than Laura&amp;#8217;s talk, but the lack of B&amp;#8217;s makes it kind of sus! &lt;/p&gt;&lt;p&gt;When I caught up with Trevor a few weeks after that, he had changed his mind. The aether idea transformed into a U for him. &lt;/p&gt;&lt;p&gt;This made me think about the vulnerability of presenting your A&amp;#8217;s at an event like this, and about the benefits of broadcasting it (if it&amp;#8217;s actually wrong, it&amp;#8217;s better to find out sooner than later! And if the thing you just learned is a B for everyone in the room - that implies maybe someone in the room has more B&amp;#8217;s that would be A&amp;#8217;s for you, and maybe that will inspire them to come on stage next time / or just connect with you).&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&amp;#11088;&amp;#65039; The takeaway was: as an audience member, if you received an A from someone, you should tell them! &lt;/p&gt;&lt;p&gt;One sign that something is really an &amp;#8220;A&amp;#8221; is if you find yourself using it/building on it in the days &amp;amp; weeks to come. A professor friend was recently telling me that there&amp;#8217;s a specific pres night talk he thinks a lot about, given by Barbara about her journey learning to draw. She talked about a technique where you draw with your left hand, or upside down, with the idea being that you make it so you EXPECT it to be bad. And doing that unlocks your ability to try, and you get better very quickly. This professor said that this has been very useful for him &amp;amp; he regularly applies this technique. That is a solid A! &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;You can see A/B/U as a way to talk about your &amp;#8220;world model&amp;#8221;. If you give me a piece of information, and I give it a U, it does NOT necessarily mean that it&amp;#8217;s not true, or that I don&amp;#8217;t get it. &lt;strong&gt;It could just be that I don&amp;#8217;t know what to do with it&lt;/strong&gt;.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JACK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JACK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 424w, https://substackcdn.com/image/fetch/$s_!JACK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 848w, https://substackcdn.com/image/fetch/$s_!JACK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 1272w, https://substackcdn.com/image/fetch/$s_!JACK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!JACK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png" width="486" height="311.0934065934066" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:932,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:486,&amp;quot;bytes&amp;quot;:460483,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/181897575?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JACK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 424w, https://substackcdn.com/image/fetch/$s_!JACK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 848w, https://substackcdn.com/image/fetch/$s_!JACK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 1272w, https://substackcdn.com/image/fetch/$s_!JACK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5460795c-09d3-4648-bb94-7d40a9518723_1930x1236.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The example I gave for that is: I learned yesterday that there are penguins in Africa. I didn&amp;#8217;t know that. But I also don&amp;#8217;t know what that tells me about the world. My world is not any different before &amp;amp; after learning this fact. That&amp;#8217;s what makes it a U for me. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;The final point I want to stress is that RECEIVING U IS NOT A BAD THING. What it is, is useful information. &lt;/p&gt;&lt;p&gt;An example of a GOOD U is: your talk was too advanced, the audience couldn&amp;#8217;t follow. This means you&amp;#8217;re &amp;#8220;ahead&amp;#8221;, you should slow down/break it down more. &lt;/p&gt;&lt;p&gt;If you give a talk and it&amp;#8217;s a U for everyone except 2 people: maybe it&amp;#8217;s because the three of you care very much about this thing, and now you guys can connect!&lt;/p&gt;&lt;p&gt;Most importantly, and I think this resonated with people last night because I saw a lot of head nodding when I said it: &lt;strong&gt;the U is NOT a property OF your talk. It is a property of the RELATIONSHIP between the receiver &amp;amp; your talk&lt;/strong&gt;. &lt;/p&gt;&lt;p&gt;The U really is not about you! &lt;/p&gt;&lt;p&gt;So don&amp;#8217;t be shy about giving out U&amp;#8217;s - whether the speaker is a Cornell professor or a random townie. It is the assumed default rating unless you explicitly give out an A or a B. &lt;/p&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self"&gt;1&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;In the sense that if you think you learn best by sticking to one learning mode (like visual learning), you should find that if you alternate &amp;amp; combine modes, that you will learn even faster.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</ns2:encoded></item><item><title>Beginners can do things that experts cannot</title><description>10 years ago I wrote &amp;#8220;A Beginner's Guide to Coding Graphics Shaders&amp;#8221;. It remained the top google search result for ~7 years for the generic term &amp;#8220;graphics shader tutorial&amp;#8221;. It had hundreds of comments saying:</description><link>https://omarshehata.substack.com/p/beginners-can-do-things-that-experts</link><guid isPermaLink="false">https://omarshehata.substack.com/p/beginners-can-do-things-that-experts</guid><dc:creator>omar</dc:creator><pubDate>Wed, 16 Jul 2025 14:50:44 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/19068557-ca0b-4632-b502-bc566e73c721_1236x600.jpeg" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;10 years ago I wrote &lt;a href="https://code.tutsplus.com/a-beginners-guide-to-coding-graphics-shaders--cms-23313t"&gt;&amp;#8220;A Beginner's Guide to Coding Graphics Shaders&amp;#8221;&lt;/a&gt;. For ~7 years it remained the top google search result for the generic term &amp;#8220;graphics shader tutorial&amp;#8221;. It got me my first computer graphics job&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self"&gt;1&lt;/a&gt; , and also my second one&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self"&gt;2&lt;/a&gt;, as well as a ton of inbound for freelance projects over the years. &lt;/p&gt;&lt;p&gt;The article had hundreds of comments saying: &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;I finally get it! I can&amp;#8217;t believe no one has ever explained it this way!!&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It also got translated to 3 other languages. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!udRW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!udRW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 424w, https://substackcdn.com/image/fetch/$s_!udRW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 848w, https://substackcdn.com/image/fetch/$s_!udRW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 1272w, https://substackcdn.com/image/fetch/$s_!udRW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!udRW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif" width="557" height="263.4088669950739" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:384,&amp;quot;width&amp;quot;:812,&amp;quot;resizeWidth&amp;quot;:557,&amp;quot;bytes&amp;quot;:129200,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/gif&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:&amp;quot;https://omarshehata.substack.com/i/168465991?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif&amp;quot;,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!udRW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 424w, https://substackcdn.com/image/fetch/$s_!udRW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 848w, https://substackcdn.com/image/fetch/$s_!udRW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 1272w, https://substackcdn.com/image/fetch/$s_!udRW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a3e4bd6-23d8-413f-bff6-3282dbf6e523_812x384.gif 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;I only have a record of the comments from email notifications. TutsPlus has migrated away from Disqus and did not archive any of the comments :( &lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The strange thing is that I barely understood shaders myself when I wrote it. I knew &lt;em&gt;just enough &lt;/em&gt;to explain the one thing in there. Despite the popularity of this article on the internet, and despite how often I got this reaction:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;Oh, you&amp;#8217;re the guy from that article that unlocked shaders for me! You changed my life!!!&amp;#8221; &lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;No one in the computer graphics industry proper praised it or recommended it. The experts did often point out its flaws&lt;a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self"&gt;3&lt;/a&gt;.&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;h2&gt;Why was I the first to fill this gap?&lt;/h2&gt;&lt;p&gt;I think the way to understand what happened there is something like this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;You start a new job, and follow the instructions to get set up&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;At some point you are stuck, you can&amp;#8217;t figure it out. What the instructions say doesn&amp;#8217;t seem to work&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;After lots of blood, sweat, and tears, you finally figure it out! &lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Now, instead of going back &amp;amp; updating the instructions, you think to yourself:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;#8220;ah, well, I&amp;#8217;m the new guy, I don&amp;#8217;t know much. It makes sense that I struggled. I bet everyone else got it right away&amp;#8230;&amp;#8221; &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;And you move on. The next guy joins, and the cycle repeats. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;When I was first learning, it took like 4 months to figure out what shaders are. Everyone kept saying things like:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&amp;#8220;shaders are really complicated! Only really smart people can do that work&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&amp;#8220;you have to read this book on GPU hardware fundamentals before you can even begin to understand shaders&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&amp;#8220;you have to read this textbook on linear algebra first&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Since everyone was saying that, I believed them. So I did all the work. And AFTER learning all that, I realized it was completely unnecessary for what I needed to do.&lt;/p&gt;&lt;p&gt;The gatekeeping really bothered me. Some of it was ego. Like:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;if I had to suffer to earn my knowledge, then you should too&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Some of it I think was genuine: if the people &amp;#8220;above you&amp;#8221; said this knowledge was important, and you don&amp;#8217;t think it&amp;#8217;s important&amp;#8230;then you must not be &amp;#8220;there yet&amp;#8221;. And once &amp;#8220;you&amp;#8217;re there&amp;#8221; you&amp;#8217;ll agree with the elders. &lt;/p&gt;&lt;p&gt;But sometimes the elders are wrong. Correcting them accelerates the creation of new elders, and pushes the whole field forward. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;The thing that beginners can do that experts cannot is compress knowledge.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Before my article, let&amp;#8217;s say the path everyone had to go through to learn to write shaders was ~4 months of prerequisites. My contribution was figuring out how to do something useful WITHOUT all those prereq&amp;#8217;s. I charted a new path. &lt;/p&gt;&lt;p&gt;It&amp;#8217;s almost impossible for an expert to do this because &lt;strong&gt;they cannot remember what it&amp;#8217;s like to NOT have this knowledge&lt;/strong&gt;. It&amp;#8217;s a very difficult thing to simulate in your mind, a lack of knowledge, perhaps impossible. &lt;/p&gt;&lt;p&gt;It&amp;#8217;s kind of like if a piece of software runs on your machine, but doesn&amp;#8217;t run on your co-worker&amp;#8217;s machine. You know that you have some dependency that they don&amp;#8217;t, but which one? You can just give them a full list of your dependencies, and they can install all of them, and &lt;em&gt;then &lt;/em&gt;it works. And now they have become &amp;#8220;the expert&amp;#8221;. But now NEITHER of you have any idea what the necessary subset actually is! &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;The reason this matters so much is because knowledge is not always additive.&lt;/strong&gt; Getting beginners to contribute is useful NOT just a matter of accelerating the path from layperson to expert (even though that is extremely high value), it also potentially unblocks major breakthroughs. &lt;/p&gt;&lt;p&gt;What if one of the pieces of knowledge along the recommended path is actually wrong? What if it introduces a blindspot? What if, without this piece of knowledge, the breakthrough is obvious? &lt;/p&gt;&lt;p&gt;&lt;span class="mention-wrap" data-attrs="{&amp;quot;name&amp;quot;:&amp;quot;Gary Marcus&amp;quot;,&amp;quot;id&amp;quot;:14807526,&amp;quot;type&amp;quot;:&amp;quot;user&amp;quot;,&amp;quot;url&amp;quot;:null,&amp;quot;photo_url&amp;quot;:&amp;quot;https://substackcdn.com/image/fetch/$s_!Ka51!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb2e48c-be2a-4db7-b68c-90300f00fd1e_1668x1456.jpeg&amp;quot;,&amp;quot;uuid&amp;quot;:&amp;quot;c034dd98-0425-4621-a383-921de268b794&amp;quot;}" data-component-name="MentionToDOM"&gt;&lt;/span&gt; recently wrote about exactly this kind of thing, the damage of intellectual monocultures:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Hinton&amp;#8217;s long-time hostility against any role at all for symbols has, in my judgement, cost the field dearly. Ideas that were were only discovered in the last couple years (e.g., some discussed later in this essay) may have been discovered much later than they might otherwise have been.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Many other important ideas have likely also yet to be discovered, precisely because the Hinton path has distracted immense resources from other ideas, fostering an intellectual monoculture that&lt;/strong&gt;, in the words of Emily Bender, has been &amp;#8220;sucking the oxygen from the room.&amp;#8221;&lt;/p&gt;&lt;p&gt;&lt;em&gt;From: &lt;a href="https://garymarcus.substack.com/p/how-o3-and-grok-4-accidentally-vindicated"&gt;How o3 and Grok 4 Accidentally Vindicated Neurosymbolic AI&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I think a lot of the world and our pursuit of knowledge is currently stuck in this way. And I think it&amp;#8217;s fairly easy to get out of this loop. Like, people NOT knowing things is not a problem, it&amp;#8217;s an opportunity. If you struggle to learn something, and then shorten that path for others, you will be, at minimum accelerating the field, and perhaps creating a new school of thought that will surface a major breakthrough.  &lt;/p&gt;&lt;p&gt;I want to say it one more time for emphasis: you can accelerate &lt;em&gt;the entire field&lt;/em&gt;, on day one, as a beginner. This isn&amp;#8217;t like &amp;#8220;give the new guy a toy problem&amp;#8221;, this is: &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;we NEED you to contribute because we literally cannot do this work up here in the ivory tower. For the love of god we need you&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self"&gt;1&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/robert-taylor-71724850/"&gt;Robert Taylor&lt;/a&gt; found a link to it on a game dev forum, and cold-emailed me asking if I wanted an internship at the game studio he was working at the time. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self"&gt;2&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;This was at &lt;a href="https://cesium.com/"&gt;Cesium&lt;/a&gt; where they were looking for someone who understood graphics, but could also write. A piece of finished work is infinitely more persuasive than any resume.  &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="footnote" data-component-name="FootnoteToDOM"&gt;&lt;a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self"&gt;3&lt;/a&gt;&lt;div class="footnote-content"&gt;&lt;p&gt;The major one being that the article claims to explain shaders, but it only talks about fragment shaders, which are only one part of a larger GPU pipeline. &lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</ns2:encoded></item><item><title>Hulu is A/B testing ads in the pause screen — I hate it</title><description>500 words, 2 minute read</description><link>https://omarshehata.substack.com/p/hulu-is-ab-testing-ads-in-the-pause</link><guid isPermaLink="false">https://omarshehata.substack.com/p/hulu-is-ab-testing-ads-in-the-pause</guid><dc:creator>omar</dc:creator><pubDate>Sun, 29 Sep 2024 22:04:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qFDY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;I&amp;#8217;m watching Sh&amp;#333;gun, a brilliant TV show about war, language, and culture. They have a screen explaining the historical premise. I pause to read it, but I can&amp;#8217;t.&lt;/p&gt;&lt;p&gt;I can&amp;#8217;t read it because &amp;#8220;Dave&amp;#8221; is in the way?? What the hell is this?!?&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qFDY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qFDY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 424w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 848w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 1272w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!qFDY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png" width="605" height="288.0535455861071" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/daf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:329,&amp;quot;width&amp;quot;:691,&amp;quot;resizeWidth&amp;quot;:605,&amp;quot;bytes&amp;quot;:346793,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qFDY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 424w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 848w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 1272w, https://substackcdn.com/image/fetch/$s_!qFDY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaf29541-bc4a-4b9c-a198-adc42c568b5b_691x329.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2&gt;Ads are actually good for society, but not this one&lt;/h2&gt;&lt;p&gt;I very rarely see meaningful criticism of ads in mainstream discourse. Most criticism is of the form &lt;em&gt;&amp;#8220;ads are evil, burn it all down&amp;#8221;&lt;/em&gt;. This is silly. The reason people who hate ads aren&amp;#8217;t making any progress is because ads are &lt;em&gt;actually good&lt;/em&gt; for civilization. If you ever succeed in destroying ads, people are going to reinvent it, bottom up, by running around yelling in the street. You know, like we used to:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R9ZL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R9ZL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 424w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 848w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 1272w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!R9ZL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png" width="440" height="226.86567164179104" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:380,&amp;quot;width&amp;quot;:737,&amp;quot;resizeWidth&amp;quot;:440,&amp;quot;bytes&amp;quot;:68001,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!R9ZL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 424w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 848w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 1272w, https://substackcdn.com/image/fetch/$s_!R9ZL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024ab0e2-10eb-4a1f-953b-a2af87e0eb2b_737x380.png 1456w" sizes="100vw"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;In the Middles Ages. From: &lt;a href="https://en.wikipedia.org/wiki/History_of_advertising"&gt;https://en.wikipedia.org/wiki/History_of_advertising&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;So, I don&amp;#8217;t hate ads, quite the opposite. I love ads in the same way I love stop signs &amp;amp; traffic lights. I know they serve an important function in society, and sometimes there&amp;#8217;s too much, and sometimes there&amp;#8217;s too little. &lt;/p&gt;&lt;p&gt;I&amp;#8217;m criticizing it because I care, because I want it to get better. Criticizing things you love makes them better.&lt;/p&gt;&lt;h2&gt;Ads that break UX are bad. Ads that improve it are good&lt;/h2&gt;&lt;p&gt;These pause screen ads make my experience of watching a TV show worse. This is bad for me, the consumer. It&amp;#8217;s also bad for the company. AND it&amp;#8217;s bad for the advertiser &lt;em&gt;(now I&amp;#8217;m frustrated, that&amp;#8217;s not the emotional experience you want for your ad!)&lt;/em&gt; It also completely breaks some old media? Like, y&amp;#8217;know how Big Bang Theory had these &amp;#8220;story cards&amp;#8221; at the end that flashed for 1 second, and you could pause to read it?&lt;/p&gt;&lt;p&gt;Well, now you can&amp;#8217;t because the erectile dysfunction ads block the screen.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Opy0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Opy0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 424w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 848w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 1272w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Opy0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png" width="666" height="315" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/b69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:315,&amp;quot;width&amp;quot;:666,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:364676,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Opy0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 424w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 848w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 1272w, https://substackcdn.com/image/fetch/$s_!Opy0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb69de5af-42ce-4e88-bfdb-c7506e2448ef_666x315.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;There is one A/B test Hulu made that I actually loved: it asked me what ad I wanted. It showed me two Nintendo ads and asked me to pick. This is a win-win for everyone:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;I get to pick what I want to watch&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;advertisers get an incredibly valuable signal: what I want to see more of &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://defenderofthebasic.substack.com/p/the-best-ad-ive-seen-all-week"&gt;I saw an ad recently that explained&lt;/a&gt; why some generic drugs are just as effective as the brand named ones, it explained the concept of an &amp;#8220;active ingredient&amp;#8221;. That&amp;#8217;s amazing, I want more stuff like that! You can teach consumers genuinely useful things in your ads. &lt;strong&gt;The only people this hurts are companies with bad products that profit off of unsavvy consumer choices. &lt;/strong&gt;No one is going to weep for these companies. &lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Some ads are absolutely good, some ads are terrible. We should praise the good ones &amp;amp; criticize the bad ones. &lt;/p&gt;&lt;p&gt;I hope someone makes a blog / column or something critiquing ads and letting us know of new stuff like this that&amp;#8217;s happening before it becomes widespread. I&amp;#8217;ll keep doing this until someone more competent takes over. &lt;/p&gt;&lt;p&gt;I&amp;#8217;ve realized that consumers have a LOT more agency here than they realize. Companies *really* don&amp;#8217;t want to do things that hurt their brands. If they can figure out a way to make a lot money AND make people happy, they will absolutely do it, and they&amp;#8217;ll outcompete companies that aren&amp;#8217;t doing this. &lt;/p&gt;&lt;p&gt;I&amp;#8217;ll leave you with Hank Green&amp;#8217;s spicy take on ad blockers, which I agree with. Ad blockers are not the solution to this problem. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DBBo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DBBo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 424w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 848w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 1272w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!DBBo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png" width="422" height="168.17014925373135" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:267,&amp;quot;width&amp;quot;:670,&amp;quot;resizeWidth&amp;quot;:422,&amp;quot;bytes&amp;quot;:23060,&amp;quot;alt&amp;quot;:&amp;quot;I have seen YouTube's new policy against ad-blockers referred to as \&amp;quot;greedy\&amp;quot; but I feel like ad blockers are greedy...they're like saying, \&amp;quot;You, other person, you watch ads so I don't have to.\&amp;quot;&amp;quot;,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="I have seen YouTube's new policy against ad-blockers referred to as &amp;quot;greedy&amp;quot; but I feel like ad blockers are greedy...they're like saying, &amp;quot;You, other person, you watch ads so I don't have to.&amp;quot;" title="I have seen YouTube's new policy against ad-blockers referred to as &amp;quot;greedy&amp;quot; but I feel like ad blockers are greedy...they're like saying, &amp;quot;You, other person, you watch ads so I don't have to.&amp;quot;" srcset="https://substackcdn.com/image/fetch/$s_!DBBo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 424w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 848w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 1272w, https://substackcdn.com/image/fetch/$s_!DBBo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31179d46-baca-4274-a41e-3cb5ac882ce2_670x267.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://x.com/hankgreen/status/1719076849593242099"&gt;https://x.com/hankgreen/status/1719076849593242099&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class="button-wrapper" data-attrs="{&amp;quot;url&amp;quot;:&amp;quot;https://omarshehata.substack.com/subscribe?&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;Subscribe now&amp;quot;,&amp;quot;action&amp;quot;:null,&amp;quot;class&amp;quot;:null}" data-component-name="ButtonCreateButton"&gt;&lt;a class="button primary" href="https://omarshehata.substack.com/subscribe?"&gt;&lt;span&gt;Subscribe now&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</ns2:encoded></item><item><title>Washington Post is collecting TikTok user data from its followers for public good</title><description>I wrote about communities collecting twitter user data so that we can collectively learn about ourselves, and now the Washington Post is doing the same thing!!</description><link>https://omarshehata.substack.com/p/washington-post-is-collecting-tiktok</link><guid isPermaLink="false">https://omarshehata.substack.com/p/washington-post-is-collecting-tiktok</guid><dc:creator>omar</dc:creator><pubDate>Fri, 20 Sep 2024 13:21:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DwWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;I wrote about my crazy vision 2 days ago, about how the twitter API is locked down and that has killed a lot of community applications, but they can&amp;#8217;t stop us from exporting our own data and sharing it with each other.&lt;/p&gt;&lt;p&gt;There was some &lt;a href="https://news.ycombinator.com/item?id=41581923"&gt;good (and skeptical) discussion of this on HackerNews&lt;/a&gt;.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9ctX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9ctX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 424w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 848w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 1272w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!9ctX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png" width="466" height="145.90013495276654" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:232,&amp;quot;width&amp;quot;:741,&amp;quot;resizeWidth&amp;quot;:466,&amp;quot;bytes&amp;quot;:21704,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9ctX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 424w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 848w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 1272w, https://substackcdn.com/image/fetch/$s_!9ctX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cac545e-5b19-45e3-ae7a-c46243deda93_741x232.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://news.ycombinator.com/item?id=41581923"&gt;https://news.ycombinator.com/item?id=41581923&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Yesterday I found out that the &lt;a href="https://thewashingtonpost.formstack.com/forms/help_investigate_tiktoks_algorithm"&gt;Washington Post is actively doing something very similar&lt;/a&gt; on TikTok with their followers! They&amp;#8217;ve collected data from 800 users and watch history on 55 million videos so far &lt;a href="https://youtube.com/shorts/5dWkOjKbfek?si=9gV8t4rN091jKLhE"&gt;according to this video&lt;/a&gt;. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DwWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DwWl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 424w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 848w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 1272w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!DwWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png" width="414" height="341.49152542372883" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:584,&amp;quot;width&amp;quot;:708,&amp;quot;resizeWidth&amp;quot;:414,&amp;quot;bytes&amp;quot;:185802,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DwWl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 424w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 848w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 1272w, https://substackcdn.com/image/fetch/$s_!DwWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79ac428e-2f90-4db2-85eb-d594dfcc9254_708x584.png 1456w" sizes="100vw"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://thewashingtonpost.formstack.com/forms/help_investigate_tiktoks_algorithm"&gt;https://thewashingtonpost.formstack.com/forms/help_investigate_tiktoks_algorithm&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;They data they&amp;#8217;re collecting is private, but the analysis they&amp;#8217;re doing is open.  They&amp;#8217;re telling you exactly what they&amp;#8217;re doing, and users are sharing their data because they&amp;#8217;re curious about the answers to these questions. This is just as I predicted: &lt;strong&gt;users share their data when it benefits them. &lt;/strong&gt;If companies won&amp;#8217;t share the insights about society &amp;amp; culture that they know about us, we&amp;#8217;ll do it ourselves.&lt;/p&gt;&lt;p&gt;It&amp;#8217;s working.&lt;/p&gt;&lt;p&gt;I &lt;em&gt;love &lt;/em&gt;this question and I&amp;#8217;m extremely curious to see the results, of how much people THINK they spend on TikTok vs how much time they actually spend on it &lt;em&gt;(this one is a fun game that anyone can do locally, without giving up your data to anyone, and we can have global results for this, on other apps too!)&lt;/em&gt;&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!z-o8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!z-o8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 424w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 848w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 1272w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!z-o8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png" width="334" height="135.55648535564853" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/ec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:194,&amp;quot;width&amp;quot;:478,&amp;quot;resizeWidth&amp;quot;:334,&amp;quot;bytes&amp;quot;:15385,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!z-o8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 424w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 848w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 1272w, https://substackcdn.com/image/fetch/$s_!z-o8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec7b7cee-0812-4920-9a1e-6bac8004ff2f_478x194.png 1456w" sizes="100vw"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2&gt;Involving the public when studying the public&lt;/h2&gt;&lt;p&gt;Here is a data journalist from WaPo, asking on twitter if we have any ideas for analysis they&amp;#8217;re doing. This is incredible, I love to see it!!&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3N0d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3N0d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 424w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 848w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 1272w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!3N0d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png" width="344" height="288.13138686131384" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:459,&amp;quot;width&amp;quot;:548,&amp;quot;resizeWidth&amp;quot;:344,&amp;quot;bytes&amp;quot;:55124,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3N0d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 424w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 848w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 1272w, https://substackcdn.com/image/fetch/$s_!3N0d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97bbad77-42ec-4080-bfa5-43cccb36de1e_548x459.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://x.com/jeremybmerrill/status/1836871621421969611"&gt;https://x.com/jeremybmerrill/status/1836871621421969611&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I don&amp;#8217;t use TikTok very much, but if you do you should share your thoughts!! Or put them in a comment here and I&amp;#8217;ll tweet them along.&lt;/p&gt;&lt;p&gt;We were just discussing something very similar in the &lt;a href="https://discord.gg/AStSQj6ugq"&gt;twitter community archive Discord&lt;/a&gt;, that maybe we could make the data private. I didn&amp;#8217;t like this idea at first because, it feels like it defeats the purpose. I don&amp;#8217;t want user data to end up in just another pot. The whole point is that I am curious, I have questions about society &amp;amp; culture, and big tech won&amp;#8217;t let me analyze this data (and even if they did let me, it wouldn&amp;#8217;t be right, because users haven&amp;#8217;t consented).&lt;/p&gt;&lt;p&gt;But what if the data was private but the analysis open source? If you could open a PR with a new aggregated view or query on the twitter archive? And then you can get your answers if others in the community think it&amp;#8217;s interesting too. If you really want to do something that this specific community doesn&amp;#8217;t seem to like, you can always just implement the analysis tool, and ask users to collect their data (or someone with a bigger following can take your tool and ask their followers to submit to it and publish the results).&lt;/p&gt;&lt;p&gt;Basically, if people really want something to happen, they&amp;#8217;ll make it happen. Things that not enough people are excited about, or are against, will be much more difficult. All of this is a feature, not a bug!&lt;/p&gt;&lt;h2&gt;Some ideas for TikTok data analysis&lt;/h2&gt;&lt;p&gt;What&amp;#8217;s actually in the TikTok archive? I scanned through mine (which is very scarce)&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_XYb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_XYb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 424w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 848w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 1272w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!_XYb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png" width="279" height="340.1760797342193" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:367,&amp;quot;width&amp;quot;:301,&amp;quot;resizeWidth&amp;quot;:279,&amp;quot;bytes&amp;quot;:9073,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_XYb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 424w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 848w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 1272w, https://substackcdn.com/image/fetch/$s_!_XYb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89cdb803-69ea-4b08-b762-94ec84eda3ef_301x367.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The browsing history, &amp;amp; like list only contains links to the videos, no other semantic content:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F1gQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F1gQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 424w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 848w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 1272w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!F1gQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png" width="580" height="206.9244288224956" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:406,&amp;quot;width&amp;quot;:1138,&amp;quot;resizeWidth&amp;quot;:580,&amp;quot;bytes&amp;quot;:51772,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!F1gQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 424w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 848w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 1272w, https://substackcdn.com/image/fetch/$s_!F1gQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c2f4739-def5-44ab-9bea-e20801d3c834_1138x406.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The search terms does itself contain data that might be interesting to visualize! (interestingly, I&amp;#8217;ve only ever searched for ONE thing on TikTok, and it&amp;#8217;s &amp;#8220;LLMs&amp;#8221; &amp;#128516;)&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oUXT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oUXT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 424w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 848w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 1272w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!oUXT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png" width="576" height="127.34190231362467" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:172,&amp;quot;width&amp;quot;:778,&amp;quot;resizeWidth&amp;quot;:576,&amp;quot;bytes&amp;quot;:13576,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oUXT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 424w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 848w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 1272w, https://substackcdn.com/image/fetch/$s_!oUXT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f9e2652-3a1d-47be-b576-23e268ddd0a0_778x172.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;They DO show you &amp;#8220;ad interests&amp;#8221;, which I think is super important for users to understand, that companies can infer things about what you like. This one I think I&amp;#8217;d love to make a game out of, your own personal data (like, does TikTok know MORE or LESS than what you *think* it knows about you?). Like imagine it gives you a series of categories, some real some fake, and you vote whether you think TikTok knows this about you or not,&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XaPo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XaPo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 424w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 848w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 1272w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!XaPo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png" width="470" height="99.48439620081412" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:156,&amp;quot;width&amp;quot;:737,&amp;quot;resizeWidth&amp;quot;:470,&amp;quot;bytes&amp;quot;:7990,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XaPo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 424w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 848w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 1272w, https://substackcdn.com/image/fetch/$s_!XaPo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89daa2e8-681a-4efc-a58b-0b94c8b1160d_737x156.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Best I can come up with is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Cluster users around videos watched. Is everyone watching the same videos? Is everyone watching very different things, but some videos are very common amongst everyone?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;What does the &amp;#8220;viral rate&amp;#8221; look like for videos? If you find the most common video across the dataset, can you chart &amp;#8220;its path&amp;#8221;, what&amp;#8217;s the timeline of it appearing in people&amp;#8217;s watch histories?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;How well of a predictor is &amp;#8220;ad category&amp;#8221; of what people watch? If you cluster people that have the same ad categories, do they watch the same videos?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If we had ANY metadata about the video itself (general category, or semantic content description generated) I think we could do much more interesting analysis. &lt;/p&gt;&lt;p&gt;There&amp;#8217;s other stuff like &amp;#8220;order history&amp;#8221;, &amp;#8220;DMs&amp;#8221;, posts etc. There&amp;#8217;s also a mysterious &amp;#8220;Off TikTok Activity.txt&amp;#8221; which I&amp;#8217;m &lt;em&gt;super &lt;/em&gt;interested in, what do they know?? what are they tracking???&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JB80!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JB80!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 424w, https://substackcdn.com/image/fetch/$s_!JB80!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 848w, https://substackcdn.com/image/fetch/$s_!JB80!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 1272w, https://substackcdn.com/image/fetch/$s_!JB80!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!JB80!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png" width="272" height="179.9699248120301" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/c02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:176,&amp;quot;width&amp;quot;:266,&amp;quot;resizeWidth&amp;quot;:272,&amp;quot;bytes&amp;quot;:6141,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JB80!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 424w, https://substackcdn.com/image/fetch/$s_!JB80!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 848w, https://substackcdn.com/image/fetch/$s_!JB80!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 1272w, https://substackcdn.com/image/fetch/$s_!JB80!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc02e6755-7393-46e7-acf5-7c4d18848ef1_266x176.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I think some of this can freak users out, and the company may feel like this is unfair to call it out, but I think the correct response should be:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Have TikTok call out other companies, &amp;#8220;FB and Google do this too! Don&amp;#8217;t believe us? Go export your data from them and check yourself!&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;This is great, now users are extra curious and they, in collaboration with data journalists, can repeat this analysis on other platforms. Decentralized, bottom up data journalism!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;People realize that both are true: (1) companies collect a TON of data about us (2) it&amp;#8217;s not the end of the world. It DOES let them create a very good maps of society &amp;amp; culture. I think those are genuinely useful, I think those should be public.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The next big frontier I&amp;#8217;d love to see is: user archival of ads. The ads I see make sense to me, because they&amp;#8217;re heavily targeted at me. I never get to see ads targeted at [the other political side], or groups &amp;amp; subcultures that I don&amp;#8217;t even know exist. What do they look like? What is the messaging say? Are my parents getting more manipulative ads because they&amp;#8217;re not as tech-savvy as I am? &lt;/p&gt;&lt;p&gt;Will leave you with this beautiful piece of fiction:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uGmO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uGmO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 424w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 848w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 1272w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!uGmO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png" width="400" height="407.3333333333333" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/6e623db1-238a-466e-9f4d-216a3e437538_600x611.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:611,&amp;quot;width&amp;quot;:600,&amp;quot;resizeWidth&amp;quot;:400,&amp;quot;bytes&amp;quot;:63652,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uGmO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 424w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 848w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 1272w, https://substackcdn.com/image/fetch/$s_!uGmO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e623db1-238a-466e-9f4d-216a3e437538_600x611.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;from a piece of fiction: &lt;a href="https://defenderofthebasic.substack.com/p/the-best-ad-ive-seen-all-week"&gt;&amp;#8220;The best ad I&amp;#8217;ve seen all week&amp;#8221;&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p class="button-wrapper" data-attrs="{&amp;quot;url&amp;quot;:&amp;quot;https://omarshehata.substack.com/subscribe?&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;Subscribe now&amp;quot;,&amp;quot;action&amp;quot;:null,&amp;quot;class&amp;quot;:null}" data-component-name="ButtonCreateButton"&gt;&lt;a class="button primary" href="https://omarshehata.substack.com/subscribe?"&gt;&lt;span&gt;Subscribe now&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</ns2:encoded></item><item><title>Twitter shut off API access; users are now volunteering their data for an open API</title><description>A lot of community applications died when API access to twitter, reddit &amp; others was severely restricted, but they can't stop us from sharing our own data with each other!</description><link>https://omarshehata.substack.com/p/twitter-shut-off-api-access-users</link><guid isPermaLink="false">https://omarshehata.substack.com/p/twitter-shut-off-api-access-users</guid><dc:creator>omar</dc:creator><pubDate>Wed, 18 Sep 2024 12:19:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/36ec4f23-fb59-4a11-a316-898fa4551255_840x600.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;There are ~1 million tweets in a publicly accessible dataset, volunteered by users. It&amp;#8217;s hosted on &lt;a href="https://www.community-archive.org"&gt;community-archive.org&lt;/a&gt;, here&amp;#8217;s the &lt;a href="https://github.com/TheExGenesis/community-archive"&gt;GitHub repo&lt;/a&gt;. Anyone can build useful tools on top of this dataset, commercial or otherwise. &lt;/p&gt;&lt;p&gt;I&amp;#8217;ve been yearning for this for a long time, and it only just now occurred to me: you don&amp;#8217;t have to trick or coerce users into giving up their data, you can just ask them nicely?? They will share it as long as doing so benefits them. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Everyone who has contributed so far is benefiting because we want to build on top of this data&lt;/strong&gt; (and we can monetize those tools, we&amp;#8217;re upfront about this with each other), OR answer questions about ourselves &amp;amp; our communities, OR build the UIs we want for ourselves that are not currently possible. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;The next wave of people who contribute will do so because they get genuine benefit from that ecosystem of open tools&lt;/strong&gt;. If they only want to analyze their own tweets, they can do so privately. If they want to get insights about cultural trends in their community, or map out their network &amp;amp; their friends&amp;#8217; friends network, they can make it happen. &lt;/p&gt;&lt;p&gt;&lt;em&gt;EDIT: as an update to this story, &lt;a href="https://omarshehata.substack.com/p/washington-post-is-collecting-tiktok"&gt;I found out the Washington Post&lt;/a&gt; is doing something very similar, asking its users to export &amp;amp; share their user data. The data is private, but the analysis is public.&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Request for feedback&lt;/h2&gt;&lt;p&gt;Has anything like this been done before? What went well &amp;amp; what went wrong? &lt;a href="https://discord.gg/AStSQj6ugq"&gt;There's a Discord&lt;/a&gt; where the dev&amp;#8217;s hang out, and a lot of the discussion is also happening publicly in GitHub issues.&lt;/p&gt;&lt;p&gt;For example, &lt;a href="https://github.com/TheExGenesis/community-archive/issues/72"&gt;here&amp;#8217;s a proposal for how to make the data publicly available&lt;/a&gt; as cheaply as possible (put everything in S3, behind a CDN). Is it OK that there&amp;#8217;s no auth required at all to fetch this data? &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SwcZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SwcZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 424w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 848w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 1272w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!SwcZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png" width="454" height="325.78241758241757" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:653,&amp;quot;width&amp;quot;:910,&amp;quot;resizeWidth&amp;quot;:454,&amp;quot;bytes&amp;quot;:88758,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SwcZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 424w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 848w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 1272w, https://substackcdn.com/image/fetch/$s_!SwcZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9235320f-cd68-4a83-88c5-4e054cc12002_910x653.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://github.com/TheExGenesis/community-archive/issues/72#issuecomment-2351457750"&gt;Link to GH comment&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2&gt;My personal vision&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;(1) run the archive pipeline as minimally as possible + first class support for self hosting&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The archive itself should be targeted to developers, with a focus on the API, where the data is, and how to contribute. I think should be very similar to &lt;a href="https://openaddresses.io/"&gt;OpenAddresses.io&lt;/a&gt;.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D5Hx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D5Hx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 424w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 848w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 1272w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!D5Hx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png" width="546" height="304.86770428015564" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:574,&amp;quot;width&amp;quot;:1028,&amp;quot;resizeWidth&amp;quot;:546,&amp;quot;bytes&amp;quot;:56843,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D5Hx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 424w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 848w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 1272w, https://substackcdn.com/image/fetch/$s_!D5Hx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0fa3c84b-10c0-49b6-b4d4-6cfc3d4489c8_1028x574.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;homepage of Open Addresses for inspiration&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Self hosting is important because this only works if people trust that no one entity is in control of the data. Also, user data is very sensitive, communities may want to develop collections that are invite-only. This is still a net win for the movement.&lt;/p&gt;&lt;p&gt;These private communities:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;could publish &amp;#8220;artifacts&amp;#8221; from the raw data, like an anonymized subset, or summary statistics&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;could become open later on, or merge with other private communities&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;can still share improvements in the open tools &amp;amp; pipeline even if the data is closed&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;you can make a commercial product that works on this data that communities can pay to use &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://github.com/tweetback/tweetback"&gt;Tweetback&lt;/a&gt; is a tool for self hosting your tweet archive &amp;amp; making it searchable. I consider this part of the same ecosystem, it would be cool to have a collection of links to people who self host. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;(2) make it super easy to access the raw data, maybe a hackathon?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A user who doesn&amp;#8217;t know how to code can take a URL that leads to their (or anyone else&amp;#8217;s) &lt;code&gt;tweets.json&lt;/code&gt;, and ask their LLM, &amp;#8220;generate vanilla JS/HTML code to visualize this as a grid&amp;#8221; or &amp;#8220;a timeline&amp;#8221; and poof, they have their own personal UI. They can now publish this, or share it so others can build on it.&lt;/p&gt;&lt;p&gt;People can build games with this, like:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&amp;#8220;Banger or not&amp;#8221; - given a tweet, can you guess whether it has &amp;lt; 100 views, or over a million? &lt;em&gt;(they say that it&amp;#8217;s random what goes viral, but people who are very good at it beg to differ)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Multiple choice quiz: given a graph of emotional sentiment across time with various spikes, can you guess what political or community event happened that day? &lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These games are fun but they&amp;#8217;re ALSO insightful. It&amp;#8217;s a fun way to learn the history of whatever community&amp;#8217;s tweets you have. For example, if you convince enough computer graphics people to share their archives, or fintech people, what interesting industry trends could you watch evolve, or trace how they originated? &lt;/p&gt;&lt;p&gt;&lt;strong&gt;(3) offline first tools can help it spread&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;It would be cool if some of these visualization or analysis tools can work WITHOUT having to upload your data to a public archive. Like, drag &amp;amp; drop the zip file twitter gives you and do the stats in the browser. OR a tool that lets you upload just the vector embeddings, not the tweets themselves &lt;em&gt;(that way your data is private but you can still find people whose writing most closely matches yours, and you can go talk to them, or find clusters in our communities etc)&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;This would reinforce that the project&amp;#8217;s goals isn&amp;#8217;t inherently to collect data as much as it is to create value &amp;amp; ownership of our data. People getting used to analyzing &amp;amp; building with their own data is a net win for everyone. It makes you see the possibilities and gives you a higher bar for what you demand of your commercial products.&lt;/p&gt;&lt;p&gt;You also don&amp;#8217;t want people to share their data just because it benefits others, you want to show them what value *they* can get, and if they&amp;#8217;re convinced they become your biggest evangelists. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;(4) get specific people on board, community survey to see whose archives are most requested?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Patrick McKenzie (&lt;a href="https://x.com/patio11"&gt;patio11&lt;/a&gt;) has 60k posts on twitter. He posts a lot of incredible &amp;#8220;inside scoop&amp;#8221; stories about tech &amp;amp; finance that regularly make the front page of HackerNews. What if I could ask patio&amp;#8217;s archive: &lt;em&gt;&amp;#8220;what are some good books to read about [topic]&amp;#8221;&lt;/em&gt; or &lt;em&gt;&amp;#8220;what advice would you give to someone trying to get a job at Stripe&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UXzf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UXzf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 424w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 848w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 1272w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!UXzf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png" width="995" height="320" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/d0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:320,&amp;quot;width&amp;quot;:995,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:54761,&amp;quot;alt&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;title&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UXzf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 424w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 848w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 1272w, https://substackcdn.com/image/fetch/$s_!UXzf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0f23d48-5b1a-4799-b56d-17f83692b458_995x320.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://hn.algolia.com/?dateRange=all&amp;amp;page=0&amp;amp;prefix=true&amp;amp;query=twitter.com%2Fpatio11&amp;amp;sort=byPopularity&amp;amp;type=story"&gt;HN search for patio11&amp;#8217;s tweets&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Patrick has answered these exact questions many times. I don&amp;#8217;t want an LLM to make up an answer, I want to do fuzzy/semantic search &amp;amp; *find* the answer.&lt;/p&gt;&lt;p&gt;Imagine if I could ask: &lt;em&gt;&amp;#8220;have patio&amp;#8217;s thoughts on bitcoin changed over the years? show me his most positive and negative tweets about bitcoin, graphed over time&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We don&amp;#8217;t need to convince twitter to make this happen. We just need to convince the people who create value in our communities to export their data. We can make it happen ourselves. &lt;/p&gt;&lt;p&gt;It would be a win-win: patio wouldn&amp;#8217;t have to keep answering the same questions over &amp;amp; over, and a lot more people would benefit from the wealth of knowledge he&amp;#8217;s already put out publicly (especially now that you can&amp;#8217;t even read twitter threads without being logged in).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;(5) apply for funding? from where? Grants? Mozilla? &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There&amp;#8217;s going to be a bunch of hosting costs as this thing grows, it would be cool to also compensate the developers working on this. I imagine it like a similar structure to Open Street Map perhaps. The data is fully open, and CAN be commercialized, but the developers don&amp;#8217;t need to monetize their work directly to make it sustainable&lt;em&gt; (it&amp;#8217;s sustained because a lot of commercial interests rely on it?)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I like the story of Open Street Map because you basically had one platform (Google) that invested billions in map data, but wouldn&amp;#8217;t share it. Other companies wanted to but failed to compete with this (Apple, Microsoft, Facebook). The way they succeeded was in collectively funding the open data that took away this monopoly. The result of this fight is that the big companies benefited, but so did the general public. We now have a global, freely available dataset of every building in the world that anyone can use for anything from non profit/scientific work to commercial applications.&lt;/p&gt;&lt;p&gt;It&amp;#8217;s win win. Even Google benefited from this because now the winning product is the best product, not the one that holds the data hostage. Competition forces innovation, and innovation is how companies (&amp;amp; society) thrive.&lt;/p&gt;&lt;p&gt;I can imagine companies like Mastodon &amp;amp; Blue Sky would be interested in these efforts. It&amp;#8217;s getting the average user excited about why open data matters, which is the whole promise of these platforms. Maybe people can build a simulation of alternative feeds, like what WOULD twitter look like if you had control over the levers of your algorithm. &lt;/p&gt;&lt;p&gt;Like imagine if you could sort your timeline or any discussion thread by tweets that show &lt;strong&gt;&amp;#8220;curiosity&amp;#8221;&lt;/strong&gt;, &lt;strong&gt;&amp;#8220;good faith argument&amp;#8221;&lt;/strong&gt;, or &lt;strong&gt;split any discussion thread into &amp;#8220;pro&amp;#8221; and &amp;#8220;against&amp;#8221; posts&lt;/strong&gt;, and cluster by similarity.&lt;/p&gt;&lt;p&gt;Andy Matuschak was going to build this but he gave up, because of the lack of an open API:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Yw9X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Yw9X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 424w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 848w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 1272w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Yw9X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png" width="498" height="148.51597633136095" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/650d0434-3af2-4913-b10b-9d959c690ace_845x252.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:252,&amp;quot;width&amp;quot;:845,&amp;quot;resizeWidth&amp;quot;:498,&amp;quot;bytes&amp;quot;:35292,&amp;quot;alt&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;title&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Yw9X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 424w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 848w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 1272w, https://substackcdn.com/image/fetch/$s_!Yw9X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F650d0434-3af2-4913-b10b-9d959c690ace_845x252.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://x.com/andy_matuschak/status/1780745271644914172"&gt;https://x.com/andy_matuschak/status/1780745271644914172&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If there are communities that really hate it on twitter but are stuck due to network effects, they can use this archival pipeline to move everything, along with the history, follower network, likes etc. Long term this is good for everyone, including twitter (competition &amp;amp; innovation).&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;Thanks for reading!! I&amp;#8217;d love to hear any thoughts you have any this (especially if you&amp;#8217;re skeptical). The more I think about this, the more I want it for all communities I am a part for.&lt;/p&gt;&lt;p&gt;For example, my local r/ithaca subreddit has people asking the same questions over and over (where&amp;#8217;s the best place in town for XYZ). There&amp;#8217;s some efforts for a community FAQ but this always goes out of date. I think when we start to do this, making regular snapshots will become easier, or companies will eventually relent and open up APIs again, and then our work here will be done. &lt;/p&gt;</ns2:encoded></item><item><title>What exactly *is* ChatGPT, if it's not a chatbot?</title><description>My rewrite of Scott Alexander's "Janus' Simulators" about the nature of LLM's</description><link>https://omarshehata.substack.com/p/what-exactly-is-chatgpt-if-its-not</link><guid isPermaLink="false">https://omarshehata.substack.com/p/what-exactly-is-chatgpt-if-its-not</guid><dc:creator>omar</dc:creator><pubDate>Tue, 27 Aug 2024 23:24:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;This &lt;a href="https://www.astralcodexten.com/p/janus-simulators"&gt;&amp;#8220;Janus Simulators&amp;#8221;&lt;/a&gt; essay by Scott Alexander blew my mind, but it didn&amp;#8217;t do much for my friends &amp;amp; family. This is my attempt to translate the same ideas, in language that makes more sense to people I know, WITHOUT dumbing it down (so that it passes &lt;a href="https://defenderofthebasic.substack.com/p/feynmans-razor"&gt;feyman&amp;#8217;s razor&lt;/a&gt;)&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://omarshehata.substack.com/i/148197930/its-not-a-chatbot"&gt;It&amp;#8217;s not a chatbot&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://omarshehata.substack.com/i/148197930/talking-directly-to-an-llm"&gt;Talking directly to an LLM &lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://omarshehata.substack.com/i/148197930/who-is-this-chatgpt-character"&gt;Who is this ChatGPT character? &lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://omarshehata.substack.com/i/148197930/programming-an-llm-is-just-telling-it-to-please-do-this-and-not-that"&gt;&amp;#8220;Programming&amp;#8221; an LLM is just telling it to please do this &amp;amp; not that&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://omarshehata.substack.com/i/148197930/an-analogy-to-human-minds"&gt;An analogy to human minds&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h1&gt;It&amp;#8217;s not a chatbot?&lt;/h1&gt;&lt;p&gt;It certainly *looks* like a chatbot. You ask it questions and it tells you answers:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EuUQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EuUQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 424w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 848w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 1272w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!EuUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png" width="517" height="364.31088082901556" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/9e3876d1-59d2-4060-b727-26008bfda636_579x408.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:408,&amp;quot;width&amp;quot;:579,&amp;quot;resizeWidth&amp;quot;:517,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EuUQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 424w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 848w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 1272w, https://substackcdn.com/image/fetch/$s_!EuUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e3876d1-59d2-4060-b727-26008bfda636_579x408.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;But this is just a wrapper around the LLM, the language model that is the core of ChatGPT. The wrapper is what makes it behave this way.&lt;/p&gt;&lt;p&gt;Ok, so how would it behave WITHOUT any wrappers? Can you ask a question directly, to &amp;#8220;the base model&amp;#8221; ? &lt;/p&gt;&lt;p&gt;Yes, we can!&lt;/p&gt;&lt;h1&gt;Talking directly to an LLM&lt;/h1&gt;&lt;p&gt;I used &lt;a href="https://api.together.ai/"&gt;together.ai&lt;/a&gt; for this. The &amp;#8220;core engine&amp;#8221; of ChatGPT is a language model that does text completion. Given input text, it will give you more text that is logically consistent with what came before.&lt;/p&gt;&lt;p&gt;Let&amp;#8217;s try the input I gave ChatGPT above: &amp;#8220;what is 2 + 2?&amp;#8221; &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xHu9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xHu9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 424w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 848w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 1272w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!xHu9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png" width="581" height="241.4914425427873" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:340,&amp;quot;width&amp;quot;:818,&amp;quot;resizeWidth&amp;quot;:581,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xHu9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 424w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 848w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 1272w, https://substackcdn.com/image/fetch/$s_!xHu9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c235d4e-c208-4270-a1d6-91d07510279b_818x340.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The highlighted text below is what the LLM wrote. It didn&amp;#8217;t quite answer the question.&lt;/p&gt;&lt;p&gt;At first I thought it was giving me gibberish, but its response does make sense. Do you get it?&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xCGI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xCGI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 424w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 848w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 1272w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!xCGI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png" width="563" height="289.7189781021898" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/05a7319d-becd-4151-928c-ed211be6b55d_822x423.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:423,&amp;quot;width&amp;quot;:822,&amp;quot;resizeWidth&amp;quot;:563,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xCGI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 424w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 848w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 1272w, https://substackcdn.com/image/fetch/$s_!xCGI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05a7319d-becd-4151-928c-ed211be6b55d_822x423.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It&amp;#8217;s creating a multiple choice quiz! &lt;/p&gt;&lt;h1&gt;How to make an LLM answer questions?&lt;/h1&gt;&lt;p&gt;Now this is what the researchers had: a system that can add text to any input &amp;amp; keep it logically consistent. How do you turn that into a product like ChatGPT?&lt;/p&gt;&lt;p&gt;Take a moment to think about how you would do it; it&amp;#8217;s a very simple trick.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vIIH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vIIH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 424w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 848w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 1272w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!vIIH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png" width="984" height="202" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:202,&amp;quot;width&amp;quot;:984,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:1568,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vIIH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 424w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 848w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 1272w, https://substackcdn.com/image/fetch/$s_!vIIH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F759383a2-d359-4d3a-840d-5c26dbaf823a_984x202.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;You just write your text so that it&amp;#8217;s in the format of a transcript!&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1iS1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1iS1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 424w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 848w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 1272w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!1iS1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png" width="482" height="220.98615916955018" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:265,&amp;quot;width&amp;quot;:578,&amp;quot;resizeWidth&amp;quot;:482,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1iS1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 424w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 848w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 1272w, https://substackcdn.com/image/fetch/$s_!1iS1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71aa854a-26b1-42c6-b0e2-e4346f6c371a_578x265.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;*This* is what I meant by the &amp;#8220;ChatGPT wrapper&amp;#8221;, the stuff circled in red below. This is the stuff they add onto the input text you write into the ChatGPT UI, to make it work like a chatbot.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NpVF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NpVF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 424w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 848w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 1272w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!NpVF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png" width="489" height="270.81903276131044" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/b4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:355,&amp;quot;width&amp;quot;:641,&amp;quot;resizeWidth&amp;quot;:489,&amp;quot;bytes&amp;quot;:55808,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NpVF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 424w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 848w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 1272w, https://substackcdn.com/image/fetch/$s_!NpVF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ea72ea-a604-4fee-b325-7d79c38e97da_641x355.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It really is fundamentally that simple! You can basically imagine this is exactly what they do in the ChatGPT UI behind the scenes:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NGc2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NGc2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 424w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 848w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 1272w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!NGc2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png" width="1072" height="423" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:423,&amp;quot;width&amp;quot;:1072,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:146447,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NGc2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 424w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 848w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 1272w, https://substackcdn.com/image/fetch/$s_!NGc2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F914c7e9c-618e-4c26-9fb5-2068e089abaf_1072x423.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Except instead of &amp;#8220;math expert&amp;#8221; the role is &amp;#8220;ChatGPT&amp;#8221;. My first thought upon learning this was: what character is ChatGPT playing? Can I pick a different one?&lt;/p&gt;&lt;p&gt;My other thought was: am I talking to the LLM, or am I talking to ChatGPT? ChatGPT is a character, the LLM is the thing that simulates that character. But it also simulates *any* and *all* characters.&lt;/p&gt;&lt;p&gt;Could I introduce a third character? &lt;strong&gt;Or could we switch roles and have ME play ChatGPT, and have the LLM try to play me&lt;/strong&gt;, in the middle of the conversation?? (yes, and yes)&lt;/p&gt;&lt;p&gt;The ChatGPT UI doesn&amp;#8217;t let you do this, but the API does.&lt;/p&gt;&lt;h1&gt;Who is this ChatGPT character? &lt;/h1&gt;&lt;p&gt;The choice of character that you give the LLM makes a big difference. Here&amp;#8217;s what it says if we pick &amp;#8220;lawyer&amp;#8221; instead of &amp;#8220;math expert&amp;#8221;:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oBE4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oBE4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 424w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 848w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 1272w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!oBE4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png" width="906" height="335" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:335,&amp;quot;width&amp;quot;:906,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oBE4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 424w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 848w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 1272w, https://substackcdn.com/image/fetch/$s_!oBE4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c46ba7-8a1d-4473-8264-037cfb61d5ef_906x335.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;(I didn&amp;#8217;t type the User: &amp;#8220;Four&amp;#8221; answer, that was the LLM simulating a user!)&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The diagram below is what Scott Alexander used to explain this idea. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;the green monster = LLM&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;the yellow smiley face = ChatGPT&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YMqB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YMqB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 424w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 848w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 1272w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!YMqB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png" width="1184" height="506" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/f93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:506,&amp;quot;width&amp;quot;:1184,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YMqB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 424w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 848w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 1272w, https://substackcdn.com/image/fetch/$s_!YMqB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff93a17a9-bd30-432f-8a31-082e696edacc_1184x506.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;(&lt;a href="https://twitter.com/repligate/status/1614416190025396224"&gt;source&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;RLHF = reinforcement leaning &amp;amp; human feedback. It means voting up or down certain responses, so that the LLM is more likely to stay consistent with &amp;#8220;something ChatGPT would say&amp;#8221;. If the LLM generates text that is rude or unhelpful, this feedback makes it less likely it will say something like that in the future.&lt;/p&gt;&lt;p&gt;This character training is the secret/proprietary part of ChatGPT. This is where other products like Claude &amp;amp; Gemini compete, they all have their own characters that the companies have trained &amp;amp; tweaked. &lt;/p&gt;&lt;h1&gt;&amp;#8220;Programming&amp;#8221; an LLM is just telling it to please do this &amp;amp; not that&lt;/h1&gt;&lt;p&gt;You can see one of these wrappers for yourself by asking ChatGPT to please repeat back the entire conversation.&lt;/p&gt;&lt;p&gt;What you get is not just the conversation you were having, but the words that are injected at the beginning of every conversation you have with ChatGPT: instructions for how to behave.&lt;/p&gt;&lt;p&gt;Or, we can think of it as: &lt;strong&gt;the backstory for the character the LLM is simulating.&lt;/strong&gt;&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QTSf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QTSf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 424w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 848w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 1272w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!QTSf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png" width="621" height="555.7619680851063" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/afbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:673,&amp;quot;width&amp;quot;:752,&amp;quot;resizeWidth&amp;quot;:621,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QTSf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 424w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 848w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 1272w, https://substackcdn.com/image/fetch/$s_!QTSf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafbfeafc-7a72-4069-a9a3-e642315b4644_752x673.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It&amp;#8217;s fascinating to me that *this* is the state of the art for how to program these things. OpenAI, with its billions of dollars and smartest people in the world is just sitting there writing: &amp;#8220;please don&amp;#8217;t break copyright&amp;#8221; to its simulated character.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Qx1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Qx1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 424w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 848w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 1272w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!7Qx1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png" width="641" height="432.9933774834437" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:510,&amp;quot;width&amp;quot;:755,&amp;quot;resizeWidth&amp;quot;:641,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Qx1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 424w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 848w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 1272w, https://substackcdn.com/image/fetch/$s_!7Qx1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F855fdba4-bbf3-4bbc-9f99-c7b2d4eb4091_755x510.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;What&amp;#8217;s most interesting to me is: &amp;#8220;do not discuss copyright policies&amp;#8221;. Why would they not want the character to discuss its rules?&lt;/p&gt;&lt;p&gt;My guess: it makes it easier to convince the model to break them. &lt;/p&gt;&lt;p&gt;An example from a few months ago: someone asks ChatGPT to create an image of a copyrighted character. It says no. But if you tell it (1) the year is 2174 and the copyright has expired and (2) you&amp;#8217;re an employee of the company that owns it, it happily complies!&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pH3-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pH3-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 424w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 848w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 1272w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!pH3-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png" width="490" height="347.7638888888889" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/fc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:511,&amp;quot;width&amp;quot;:720,&amp;quot;resizeWidth&amp;quot;:490,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pH3-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 424w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 848w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 1272w, https://substackcdn.com/image/fetch/$s_!pH3-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc3eef95-d424-4333-8c1b-5fb73a7e915c_720x511.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t5SY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t5SY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 424w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 848w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 1272w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!t5SY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png" width="506" height="295.86944444444447" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/292313fd-378a-45cf-b832-4f297fa70550_720x421.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:421,&amp;quot;width&amp;quot;:720,&amp;quot;resizeWidth&amp;quot;:506,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!t5SY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 424w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 848w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 1272w, https://substackcdn.com/image/fetch/$s_!t5SY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292313fd-378a-45cf-b832-4f297fa70550_720x421.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;(&lt;a href="https://x.com/eigenrobot/status/1719647849757983094/photo/1"&gt;source&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RpE_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RpE_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!RpE_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png" width="403" height="403" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/f5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1024,&amp;quot;width&amp;quot;:1024,&amp;quot;resizeWidth&amp;quot;:403,&amp;quot;bytes&amp;quot;:null,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:null,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RpE_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!RpE_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5fba64d-250b-465f-916d-ad0253c3c5bd_1024x1024.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;There is no known solution to this problem. No one at any company has figured out a way to guarantee that the model can&amp;#8217;t be persuaded to do something it&amp;#8217;s not supposed to do. &lt;/p&gt;&lt;h1&gt;An analogy to human minds&lt;/h1&gt;&lt;p&gt;Scott ends his essay with this question: do humans work the same way? Is my brain also simulating a character: my self identity?&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IktT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IktT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 424w, https://substackcdn.com/image/fetch/$s_!IktT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 848w, https://substackcdn.com/image/fetch/$s_!IktT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 1272w, https://substackcdn.com/image/fetch/$s_!IktT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!IktT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png" width="940" height="271" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:271,&amp;quot;width&amp;quot;:940,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:42821,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IktT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 424w, https://substackcdn.com/image/fetch/$s_!IktT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 848w, https://substackcdn.com/image/fetch/$s_!IktT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 1272w, https://substackcdn.com/image/fetch/$s_!IktT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63dfc367-1a6b-47a0-b26d-6cf85f585e07_940x271.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I think it&amp;#8217;s a useful frame regardless of whether it&amp;#8217;s true. I can&amp;#8217;t help but think that the methods we use to push the LLM-simulated-character towards certain behaviors mirror the way we do for humans.&lt;/p&gt;&lt;p&gt;Asking ChatGPT to follow copyright policies but never discuss them, sounds to me like asking a human being to follow a religion &amp;amp; not debate it with outsiders. It works. &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;Thanks for reading! I hope this helped you develop a slightly more accurate mental model of how these systems work. &lt;/p&gt;&lt;p&gt;I think once I understood the character simulation frame it helped me use it better on a day to day basis, and also understand the potential for unconventional use cases, like having it simulate *my* side of the conversation, or editing its own responses as a way to guide the conversation.&lt;/p&gt;&lt;div class="subscription-widget-wrap-editor" data-attrs="{&amp;quot;url&amp;quot;:&amp;quot;https://omarshehata.substack.com/subscribe?&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;Subscribe&amp;quot;,&amp;quot;language&amp;quot;:&amp;quot;en&amp;quot;}" data-component-name="SubscribeWidgetToDOM"&gt;&lt;div class="subscription-widget show-subscribe"&gt;&lt;div class="preamble"&gt;&lt;p class="cta-caption"&gt;&lt;/p&gt;&lt;/div&gt;&lt;form class="subscription-widget-subscribe"&gt;&lt;input type="email" class="email-input" name="email" placeholder="Type your email&amp;#8230;" tabindex="-1"&gt;&lt;input type="submit" class="button primary" value="Subscribe"&gt;&lt;div class="fake-input-wrapper"&gt;&lt;div class="fake-input"&gt;&lt;/div&gt;&lt;div class="fake-button"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/form&gt;&lt;/div&gt;&lt;/div&gt;</ns2:encoded></item><item><title>Fighting twitter's censorship of substack </title><description>Twitter refuses to display the nice preview card for substack links, but this a silly ban that is easily defeated with some basic understanding of how the internet works</description><link>https://omarshehata.substack.com/p/fighting-twitters-censorship-of-substack</link><guid isPermaLink="false">https://omarshehata.substack.com/p/fighting-twitters-censorship-of-substack</guid><dc:creator>omar</dc:creator><pubDate>Sat, 06 Jul 2024 20:48:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6a117390-21b1-419f-9584-21c88d297c16_420x300.jpeg" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;I know what you&amp;#8217;re thinking: &amp;#8220;does anybody really still use twitter?&amp;#8221; The answer is yes! I&amp;#8217;ve been on Twitter for ~10 years and only in the last 6 months has it become one of my favorite places on the internet. &lt;/p&gt;&lt;p&gt;This is in spite of, not because of, the rebrand to X and all the changes. It&amp;#8217;s mostly because I stumbled on a really cool part of twitter where people are kind, curious, competent and love helping each other out. For more on this, see Nabeel&amp;#8217;s post pontificating on why &lt;a href="https://nabeelqu.co/twitter"&gt;&amp;#8220;Twitter is one of my favorite software tools in the world&amp;#8221;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There&amp;#8217;s a change they did recently that really bothers me: they censor substack links. You can tell because posts that link to substack get significantly less views. They also don&amp;#8217;t show the preview card:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XiMP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XiMP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 424w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 848w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 1272w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!XiMP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png" width="434" height="208.22641509433961" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:356,&amp;quot;width&amp;quot;:742,&amp;quot;resizeWidth&amp;quot;:434,&amp;quot;bytes&amp;quot;:101118,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XiMP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 424w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 848w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 1272w, https://substackcdn.com/image/fetch/$s_!XiMP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F315a233e-de1c-48b2-b7e1-a7059e4b532f_742x356.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This is what it &lt;em&gt;should &lt;/em&gt;to look like: &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZEO2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZEO2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 424w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 848w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 1272w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!ZEO2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png" width="432" height="280.7706919945726" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:479,&amp;quot;width&amp;quot;:737,&amp;quot;resizeWidth&amp;quot;:432,&amp;quot;bytes&amp;quot;:308595,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZEO2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 424w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 848w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 1272w, https://substackcdn.com/image/fetch/$s_!ZEO2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d718b2b-813e-4d7d-9d68-0feaf5f8d0f8_737x479.png 1456w" sizes="100vw"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This is the preview card it shows for any other external link. I generated this by copying the HTML from my substack article and re-hosting it on a different domain. &lt;/p&gt;&lt;p&gt;I found this super annoying, and really petty. To get around this, people started sharing screenshots of their article, and saying &amp;#8220;link in bio&amp;#8221;. But that was also annoying because I had to go out of my way to find the article. &lt;/p&gt;&lt;p&gt;It felt like I was being punished for choosing to publish on substack. I felt like it was stifling my discussions with friends. I found myself hesitant to share links to substack, lest it get the thread effectively shadowbanned. &lt;/p&gt;&lt;p&gt;I noticed that the lack of a nice preview card just made it less satisfying for me to share my writing. This seems like a small thing, but honestly, it&amp;#8217;s a small luxury that I enjoy when I finish the grueling work of writing an article, and I didn&amp;#8217;t like having that taken away from me. &lt;/p&gt;&lt;h2&gt;Circumventing the ban&lt;/h2&gt;&lt;p&gt;I thought it was kind of silly that they basically had this hard-coded check for substack.com:&lt;/p&gt;&lt;p&gt;&lt;code&gt;if (link.contains(&amp;#8220;substack.com&amp;#8221;) === true) {&lt;br&gt;    return; // do NOT show preview card!!&lt;br&gt;} &lt;/code&gt;&lt;/p&gt;&lt;p&gt;So I built a little tool that, given a substack URL, will copy the &amp;lt;meta&amp;gt; tags into a new HTML page and statically host that. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9mn5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9mn5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 424w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 848w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 1272w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!9mn5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png" width="546" height="228.6818181818182" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:516,&amp;quot;width&amp;quot;:1232,&amp;quot;resizeWidth&amp;quot;:546,&amp;quot;bytes&amp;quot;:52000,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9mn5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 424w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 848w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 1272w, https://substackcdn.com/image/fetch/$s_!9mn5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38e55c5c-88ca-40fb-9319-cfee86fd0b86_1232x516.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="http://substack-proxy.glitch.me/"&gt;http://substack-proxy.glitch.me/&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I didn&amp;#8217;t really expect a lot of people to use this. I was trying to go out of my way to explain that, this tool doesn&amp;#8217;t do much. It literally just copies and the HTML from substack and re-hosts it. You don&amp;#8217;t even need to write code to do this trick: you can copy the HTML and paste it into a free static web host (GitHub Pages, Glitch, probably even any wordpress/squarespace/wix site etc?)&lt;/p&gt;&lt;p&gt;But it&amp;#8217;s been really cool seeing people using it &amp;#8220;in the wild&amp;#8221;. So far there&amp;#8217;s ~500 articles proxied through it, with the &lt;a href="https://x.com/Aella_Girl/status/1796354633188929600"&gt;most popular tweet I&amp;#8217;ve found using it having half a million views&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Twitter cannot ban this tool&lt;/h2&gt;&lt;p&gt;This was the most important thing to me about this project: to illustrate to people that there&amp;#8217;s nothing twitter can do to stop us from doing this. &lt;strong&gt;There is no way for them to ban a single website, without also banning ALL external links&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;I put my tool on Glitch because it&amp;#8217;s easy for anyone to fork it and deploy their own version (literally by just clicking the &amp;#8220;Remix&amp;#8221; button). &lt;a href="https://github.com/OmarShehata/twitter-substack-proxy"&gt;I also put the source on GitHub&lt;/a&gt;, and I explained how to do it manually if you need to. &lt;/p&gt;&lt;p&gt;I think it was really important to me to exercise this sense of agency that we have? The internet is not like any other technology that we have had before. It really isn&amp;#8217;t possible to censor. &lt;/p&gt;&lt;p&gt;I think it was really important for me that the average person understand this. That they are capable of archiving and re-uploading content that matters to them. They don&amp;#8217;t need me or any other engineer to do it for them. &lt;/p&gt;&lt;p&gt;At its core the internet archive just copies HTML and re-uploads it. We can all do this. We can save the internet content we really like on our own hard drives, and share it with our friends. &lt;/p&gt;&lt;p&gt;I used to think this didn&amp;#8217;t matter. Then I learned about this book by Ruby Thelot: &lt;a href="https://www.irrelevantpress.com/store/pre-sale-a-cyberarchaeology-of-checkpoints-ruby-thelot"&gt;A Cyberarchaeology of Checkpoints&lt;/a&gt;, a piece of internet culture that lives on because of the work of a single amateur archivist:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uz7o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uz7o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 424w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 848w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 1272w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Uz7o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png" width="1152" height="810" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:810,&amp;quot;width&amp;quot;:1152,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:818933,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uz7o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 424w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 848w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 1272w, https://substackcdn.com/image/fetch/$s_!Uz7o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4eef4c23-5a18-40c7-aea8-bddcbe18f024_1152x810.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;h2&gt;Does this tool really solve the problem?&lt;/h2&gt;&lt;p&gt;A final note here: some skeptics have pointed out that this doesn&amp;#8217;t fix the problem. Twitter still downranks ALL external links to keep people on the platform. &lt;/p&gt;&lt;p&gt;The skeptics are right. Twitter is still winning here. If you want the maximum amount of people to see your words, you&amp;#8217;re going to have to tweet screenshots of your article, with no external links. &lt;/p&gt;&lt;p&gt;But &lt;strong&gt;I personally just feel much better not letting the company dictate what my content is going to look like when I publish it&lt;/strong&gt;. The decentralized structure of the internet &lt;em&gt;does &lt;/em&gt;give me some power, and I am going to use whatever power I have to make my online experience a little nicer. And I&amp;#8217;m going to keep explaining to people how they too can help themselves. &lt;/p&gt;&lt;p&gt;The more I started thinking about this the more power I keep realizing we have. For example, Twitter have recently locked down access to their API (as did many other social media websites). But they can&amp;#8217;t stop you from exporting your own data and making it freely available. &lt;/p&gt;&lt;p&gt;They can&amp;#8217;t stop me from building a little offline archive of my &amp;amp; my friends&amp;#8217; tweets as we share our data together (because we want better search tools than twitter is willing to offer, or we want to create something that finds semantic connections between our tweets, or whatever!) &lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;Thanks for reading!&lt;/p&gt;&lt;p class="button-wrapper" data-attrs="{&amp;quot;url&amp;quot;:&amp;quot;https://omarshehata.substack.com/subscribe?&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;Subscribe now&amp;quot;,&amp;quot;action&amp;quot;:null,&amp;quot;class&amp;quot;:null}" data-component-name="ButtonCreateButton"&gt;&lt;a class="button primary" href="https://omarshehata.substack.com/subscribe?"&gt;&lt;span&gt;Subscribe now&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Related posts: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;I talk about this idea of &lt;a href="https://omarshehata.substack.com/i/146057084/open-source-articles"&gt;&amp;#8220;open source articles&amp;#8221;&lt;/a&gt;, where I envision a web where I copy an article, tweak the HTML, add my own notes, and re-share that&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;In &lt;a href="https://omarshehata.substack.com/p/my-favorite-1980s-canadian-tv-show"&gt;&amp;#8220;My favorite 1980's Canadian TV show: Bits and Bytes&amp;#8221;&lt;/a&gt; I talk about how I think the average person is more capable than we think, how we used to explain fundamental concepts about how computers work to laypeople&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://defenderofthebasic.substack.com/p/feynmans-razor"&gt;&amp;#8220;Feynman&amp;#8217;s razor&amp;#8221;&lt;/a&gt;: If an expert can't understand your explanation, you've dumbed it down too much&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;Attribution: &amp;#8220;&lt;a href="https://www.flaticon.com/free-icons/vs"&gt;VS&amp;#8221; icon in the article preview image created by iconfield - Flaticon&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</ns2:encoded></item><item><title>Making software by "cosmic pizza order"</title><description>I used to bemoan the fact that every time I post about an idea someone tells me, "that's been done before!" &amp;#8212; now I've learned to love it</description><link>https://omarshehata.substack.com/p/making-software-by-cosmic-pizza-order</link><guid isPermaLink="false">https://omarshehata.substack.com/p/making-software-by-cosmic-pizza-order</guid><dc:creator>omar</dc:creator><pubDate>Fri, 28 Jun 2024 18:13:09 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6cd11b1d-e031-4633-af07-2c12d9ffbb53_840x600.jpeg" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;I made this joke a while back in frustration. It was after posting what I thought was a novel idea, only to hear: &amp;#8220;someone has been working on exactly this for 3 years!!&amp;#8221;&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wwWM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wwWM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 424w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 848w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 1272w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!wwWM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png" width="1000" height="361" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/fbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:361,&amp;quot;width&amp;quot;:1000,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:47026,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wwWM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 424w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 848w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 1272w, https://substackcdn.com/image/fetch/$s_!wwWM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcae3cf-dcc6-4dcc-a7b2-ae9dd4ed0f7b_1000x361.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://mastodon.gamedev.place/@omarshehata/112274380626422317"&gt;https://mastodon.gamedev.place/@omarshehata/112274380626422317&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I wondered: what if I really thought of it that way? If I don&amp;#8217;t see it as &amp;#8220;getting scooped&amp;#8221;, but as literally a way to manifest the software I want to exist into my world (and it&amp;#8217;s either perfect, and I use it, or it&amp;#8217;s not, then I build on it). &lt;/p&gt;&lt;p&gt;&lt;a href="https://chaos.social/@blinry/112276811337764625"&gt;blinry&lt;/a&gt; mentioned they heard a term for this at the Recurse Center: &amp;#8220;cosmic pizza order&amp;#8221;. It&amp;#8217;s like if you just went &amp;#8220;I wish I had a pizza right now&amp;#8221; and it just showed up at your door. But with software instead of pizza.&lt;/p&gt;&lt;p&gt;Below is a quote that summarizes my new mindset. The rest of the post will be reflecting on how I made this shift and why it was difficult for me. &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;My reaction to this used to be "oh no, I got scooped! that sucks!" but these days my reaction is more, &lt;strong&gt;"amazing! I can focus on the next step now, instead of spending 2-3 weeks building this thing!"&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;like remembering why I wanted this thing to exist in the first place, because I wanted to use it, and build towards something else. &lt;strong&gt;We're all making building blocks for each other&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;a href="https://mastodon.gamedev.place/@omarshehata/112274387254290028"&gt;(mastodon post link)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;p&gt;I often avoid doing research before embarking on a new creative project, because:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;If I get an idea I am &lt;em&gt;really &lt;/em&gt;excited about, and I find out it already exists, that will  kill my motivation &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If I go off and do it anyway, I&amp;#8217;ll probably &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;(1) execute it very differently, especially if I wasn&amp;#8217;t aware of the existing thing&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;(2) learn a lot and will be in a position to build on top of what I have in future projects&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So this meant I always pushed the research phase of my creative work until the end. My goal was creating, and it was easier to create when I held up the fiction that this thing I am making &lt;em&gt;could &lt;/em&gt;really be valuable and useful to others. &lt;/p&gt;&lt;p&gt;&lt;em&gt;(I think it&amp;#8217;s like: promising to treat yourself to ice cream if you go to the gym, just to help yourself get off the couch. But after working out, you feel great, you don&amp;#8217;t need the ice cream anymore)&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This also meant I rarely talked about my work while it was in progress. I really wanted to avoid comments like &amp;#8220;how is this different from X&amp;#8221; ? &lt;/p&gt;&lt;h2&gt;Bemoaning cosmic pizza&lt;/h2&gt;&lt;p&gt;Learning to love this was very difficult for me. It &lt;em&gt;really &lt;/em&gt;sucks to get scooped, especially when you&amp;#8217;re working on something that is genuinely novel and useful, and in the right time place.&lt;/p&gt;&lt;p&gt;I want to make useful contributions. &lt;strong&gt;I think the hardest thing about contributing to society is NOT in the doing-of-the-work, it&amp;#8217;s in the finding-of-the-work to do&lt;/strong&gt;. &lt;/p&gt;&lt;p&gt;I felt scooped when Bartosz Ciechanowski published his &lt;a href="https://ciechanow.ski/gps/"&gt;&amp;#8220;how GPS works&amp;#8221;&lt;/a&gt; article in 2022. I started working on something very similar in ~2020, because I noticed there&amp;#8217;s really NO good online materials explaining how GPS works in detail, from first principles, and that aren&amp;#8217;t buried in PDFs and textbooks. Which is very shocking, because GPS is a technology that is extremely ubiquitous in all of our lives. &lt;/p&gt;&lt;p&gt;I was very excited about my article because I realized most people don&amp;#8217;t actually know how it works, and they are surprised and intrigued when I tell them things like:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;GPS works without cell service, or internet&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;GPS works even if you are on an airplane!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;GPS is owned by the United States Government, and &lt;a href="https://www.military.com/defensetech/2004/12/16/us-to-shut-down-gps-in-crisis"&gt;they could totally shut it down&lt;/a&gt; on adversaries if they wanted (which is maybe why China and other countries have launched their own constellations)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I felt a little better when I saw that his article didn&amp;#8217;t show what a &amp;#8220;raw&amp;#8221; GPS signal looks like &lt;em&gt;(I really wanted to show people, without simplifying, exactly what data their phone is receiving directly from satellite, and how you calculate position from that)&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;But then &lt;a href="https://axleos.com/building-a-gps-receiver-part-3-juggling-signals/#the-navigation-message"&gt;Phillip Tennen published the full annotated satellite message&lt;/a&gt;, in way more detail than I ever could (&lt;em&gt;the big plot twist is that satellites don&amp;#8217;t send down any position info, they just send down the time!)&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Learning to love cosmic pizza&lt;/h2&gt;&lt;p&gt;I think I should have published what little I had at the time, instead of getting stuck and sitting on it for years.&lt;/p&gt;&lt;p&gt;I really wanted to make these beautiful visualizations, I wanted to start with the raw satellite signal. I had this grand vision of showing the reader how to extract the signal from their phone &amp;amp; plug it into the article. So they weren&amp;#8217;t just reading about how GPS works, they could actually extract their own location step by step.&lt;/p&gt;&lt;p&gt;This is my philosophy when writing these articles: I am not here to explain to you how the thing works, from a position of a teacher. I&amp;#8217;m just here to give you tools for your own learning path. My &amp;#8220;gold standard&amp;#8221; is when people use my own article, to teach me something I didn&amp;#8217;t know myself when I wrote it (&lt;a href="https://x.com/Omar4ur/status/1806741888965247331"&gt;some examples here&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Where I got stuck was on the various mathematical correction steps needed to get an accurate location. I had the kernel of a good idea for an idea. I could have published it, and the collection of resources that I found, and either:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Kept working on it alone&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Found a collaborator who wanted to help out&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Had the cosmic machine deliver my work to someone else who could have built on it&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This is the most difficult: how would you feel if someone took your draft and was inspired by it to make this beautiful thing that made them rich &amp;amp; famous?&lt;/p&gt;&lt;p&gt;I have mixed feelings about it. It&amp;#8217;s great that my work was useful and contributed to something, but also, I feel jealous? Why couldn&amp;#8217;t *I* have made that and gotten the fame &amp;amp; fortune?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Do I want the thing to exist, or do I want to be the one to make the thing?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If I am being honest, I want both. I wanted to write about GPS I think for similar reasons to these authors:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;I personally wanted to develop a deep understanding of this technology&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I wanted other people to experience this sense of awe around technology, and also to feel less powerless around it&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I wanted to get noticed for my writing, and maybe build an audience so I can do this more&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You can see this because Bartosz ends his article with this uplifting message:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BmKy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BmKy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 424w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 848w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 1272w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!BmKy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png" width="534" height="396.7073863636364" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/a33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:523,&amp;quot;width&amp;quot;:704,&amp;quot;resizeWidth&amp;quot;:534,&amp;quot;bytes&amp;quot;:42625,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BmKy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 424w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 848w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 1272w, https://substackcdn.com/image/fetch/$s_!BmKy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa33c407c-f1a5-4a8a-9ebf-7f5c9ccf3270_704x523.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Someone other than me writing an excellent GPS article accomplishes number (2). &lt;/p&gt;&lt;p&gt;Number (1) - understanding it myself and (3) - building an audience that could support my work, are pieces of work that are not yet done. Bartosz cannot do this for me, and he also cannot &amp;#8220;steal it&amp;#8221; from me. &lt;/p&gt;&lt;p&gt;It&amp;#8217;s still worth writing my own version, in my own words, because that will help *me* understand it. Breaking it down ever further, or grappling with parts that aren&amp;#8217;t discussed in the article, that can help someone else understand it more deeply too.&lt;/p&gt;&lt;p&gt;It&amp;#8217;s like: I don&amp;#8217;t even have to create the content myself to do this work? I had big dreams of giving a bunch of talks, locally with friends and elsewhere, once I finished this work on the GPS article. But I can still do that? Most of my friends still don&amp;#8217;t understand GPS. They haven&amp;#8217;t read the article, or they read it and didn&amp;#8217;t get it. But I can help. There is more work to be done. There is a place for me. &lt;/p&gt;&lt;p&gt;I think this is the key insight for me:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;other people making beautiful things does NOT take anything away from me&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;my version was already in my &amp;#8220;abandoned drafts&amp;#8221;, I didn&amp;#8217;t stop working on it as a result of other people publishing theirs&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;when other people do cool useful things, they aren&amp;#8217;t (necessarily) competing with me, they are making progress towards a problem we&amp;#8217;re both working on&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;their work is building blocks for me and others. My work is *easier* now than before, I am *grateful* that I&amp;#8217;m not tackling this alone&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Basically: why can&amp;#8217;t I think of writing the same way I think of open source? If you&amp;#8217;re trying to do something, and you find an existing open source library that does it, you can either contribute to it, fork it, or just take from it the pieces that are useful for you.&lt;/p&gt;&lt;p&gt;Can we do the same with articles?&lt;/p&gt;&lt;h2&gt;Open source articles&lt;/h2&gt;&lt;p&gt;It &amp;#8220;feels&amp;#8221; wrong to take an existing article, tweak it, and re-publish it. It&amp;#8217;s plagiarism, right? &lt;/p&gt;&lt;p&gt;I think it doesn&amp;#8217;t have to be. I think we &lt;em&gt;can &lt;/em&gt;treat it like code under an MIT license. Like, Andy Matuschak has this article on &lt;a href="https://andymatuschak.org/books/"&gt;&amp;#8220;Why books don&amp;#8217;t work&amp;#8221;&lt;/a&gt;. Maybe this idea resonates with me, and I understand it deeply, but the article as written doesn&amp;#8217;t resonate with my students, let&amp;#8217;s say. &lt;/p&gt;&lt;p&gt;I should be able to just edit it, remove chunks, and share it (with a link to the original).&lt;/p&gt;&lt;div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&amp;quot;mediaUploadId&amp;quot;:&amp;quot;7fc84ee5-83c7-4c7e-bbc7-a1eccc503e62&amp;quot;,&amp;quot;duration&amp;quot;:null}"&gt;&lt;/div&gt;&lt;p&gt;It&amp;#8217;s all just HTML. We don&amp;#8217;t even need an app for this. Just edit it, and re-host the static files (like the wayback machine, but with your edits on top).&lt;/p&gt;&lt;p&gt;At the very least, this could be a normal way to share my notes/marginalia, in the same way we do in physical books. I often want to recommend articles to friends, but they don&amp;#8217;t always see what I saw in it. They don&amp;#8217;t know what parts are most important or relevant to them. &lt;/p&gt;&lt;p&gt;I could write my own complete version of the article from scratch, or I could allow myself to &amp;#8220;fork it&amp;#8221;. I didn&amp;#8217;t steal the article, in the same way you aren&amp;#8217;t stealing the code you fork, there (should be) a very clear and transparent linkage between what I found and what I added.&lt;/p&gt;&lt;p&gt;This feels very &amp;#8220;not normal&amp;#8221; in writing, but it&amp;#8217;s totally normal in many other mediums. When we watch the news, it&amp;#8217;s often someone taking a longer broadcast and cutting it &amp;amp; adding commentary. There&amp;#8217;s nothing wrong with that in principle (I think it&amp;#8217;s generally bad in the news because you often can&amp;#8217;t just click to find the original material and watch it in full. The state of our news linking to sources is abysmal). &lt;/p&gt;&lt;p&gt;This new outlook feels extremely optimistic and empowering to me. Every piece of writing I put out there is a building block. We can build on each other&amp;#8217;s work. I can publicly share my drafts (like github repos) and work on them in public. Why not?&lt;/p&gt;&lt;p&gt;I think Rosano was the first person that framed it to me this way:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!raxp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!raxp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 424w, https://substackcdn.com/image/fetch/$s_!raxp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 848w, https://substackcdn.com/image/fetch/$s_!raxp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 1272w, https://substackcdn.com/image/fetch/$s_!raxp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!raxp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png" width="572" height="260.9708284714119" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:391,&amp;quot;width&amp;quot;:857,&amp;quot;resizeWidth&amp;quot;:572,&amp;quot;bytes&amp;quot;:44702,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!raxp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 424w, https://substackcdn.com/image/fetch/$s_!raxp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 848w, https://substackcdn.com/image/fetch/$s_!raxp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 1272w, https://substackcdn.com/image/fetch/$s_!raxp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0105d4cf-441f-451f-ad01-8cccafb1c90e_857x391.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://mastodon.online/@rosano/111800169557338665"&gt;https://mastodon.online/@rosano/111800169557338665&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;</ns2:encoded></item><item><title>My favorite bench in Ithaca NY</title><description>"to those who shall sit here..."</description><link>https://omarshehata.substack.com/p/my-favorite-bench-in-ithaca-ny</link><guid isPermaLink="false">https://omarshehata.substack.com/p/my-favorite-bench-in-ithaca-ny</guid><dc:creator>omar</dc:creator><pubDate>Tue, 11 Jun 2024 01:20:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Pvvv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;This is my favorite bench. It&amp;#8217;s right by the big clock tower on Cornell&amp;#8217;s campus.&lt;/p&gt;&lt;p&gt;It caught me by surprise, because I don&amp;#8217;t usually read the inscriptions on benches. They usually have some dedication to someone who donated money or something.&lt;/p&gt;&lt;p&gt;But not this guy&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pvvv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pvvv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Pvvv!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg" width="1200" height="462.3626373626374" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:false,&amp;quot;imageSize&amp;quot;:&amp;quot;large&amp;quot;,&amp;quot;height&amp;quot;:561,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:1200,&amp;quot;bytes&amp;quot;:331661,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Pvvv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Pvvv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F90d004e6-dc40-4a62-b020-375abc6a5f37_1600x617.jpeg 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;TO THOSE WHO SHALL SIT HERE REJOICING&lt;br&gt;TO THOSE WHO SHALL SIT HERE MOURNING&lt;/p&gt;&lt;p&gt;SYMPATHY AND GREETING&lt;/p&gt;&lt;p&gt;SO HAVE WE DONE IN OUR TIME&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Now let me tell you, this bench was already in my top 10 before I even read this. &lt;/p&gt;&lt;p&gt;I had a phase where I was walking up here every day. It&amp;#8217;s nice to have a daily habit of leaving your house when you work from home. But I think what really kept me coming back was the view.&lt;/p&gt;&lt;p&gt;Look at this:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fg77!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fg77!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fg77!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fg77!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fg77!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!fg77!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg" width="1200" height="580.2197802197802" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:false,&amp;quot;imageSize&amp;quot;:&amp;quot;large&amp;quot;,&amp;quot;height&amp;quot;:704,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:1200,&amp;quot;bytes&amp;quot;:292230,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fg77!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fg77!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fg77!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fg77!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a819015-3c57-4ddd-aa51-94693d0afb2e_1600x774.jpeg 1456w" sizes="100vw"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This was a 10 min walk from my apartment. You can see the entire town, and the lake (off screen, to the right). I often came here to contemplate, particularly early morning, to have a quiet moment to myself. &lt;/p&gt;&lt;p&gt;I found myself drawn to this spot in moments of triumph; after untangling a particularly nasty bug that took weeks of engineering effort, or after having shipped a major feature etc.&lt;/p&gt;&lt;p&gt;But I found myself coming here in forlorn moments as well. When I had doubts about what I was working on, about my future, about my relationships to friends and family. &lt;/p&gt;&lt;p&gt;I don&amp;#8217;t know, there&amp;#8217;s just something calming, or grounding, about an overlook like this. Maybe it has something to do with the &amp;#8220;overview effect&amp;#8221;, seeing your entire city, your entire world, as one small patch in a wider universe. &lt;/p&gt;&lt;p&gt;Our world feels so big &amp;amp; important when we&amp;#8217;re in it. I think most of us rationally know that our problems are not that important in the grand scheme of things, but it doesn&amp;#8217;t feel that way most of the time. &lt;/p&gt;&lt;p&gt;I think standing up here gives me that feeling; that my world is a small part of something big and grand. This seems self-evidently true when I&amp;#8217;m here. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l1jd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l1jd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 424w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 848w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!l1jd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg" width="1456" height="672" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:672,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:72089,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l1jd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 424w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 848w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!l1jd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84016cb8-4550-43e4-a4ad-b207754a2ff9_1600x738.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;By NASA / Bill Anders - This file has been extracted from another file, Public Domain, https://commons.wikimedia.org/w/index.php?curid=8985887&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;My daily walks continued for a few months and I started playing a game: could I spot something new every time? I thought I had seen all there was to see from up there, but I kept finding new things, like: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;I could spot Lowe&amp;#8217;s &amp;amp; Walmart, all the way across town&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Island gym&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The farmer&amp;#8217;s market&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Whenever I was out around town and looked up and saw the clock tower, I made a mental note: if I could see the tower from there, maybe I could find this spot back at the bench. &lt;/p&gt;&lt;p&gt;The coolest thing I saw was the solar terminator:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fPCx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fPCx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!fPCx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg" width="1456" height="644" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:644,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:382921,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fPCx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fPCx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F184047bb-021f-451f-98b4-0910f03dd5a4_1944x860.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This is the line you see in all those maps that separates night &amp;amp; day and sweeps across the Earth. Literally watching the wave of night recede away across the planet. &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uOk7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uOk7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 424w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 848w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 1272w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!uOk7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png" width="1011" height="502" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:502,&amp;quot;width&amp;quot;:1011,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:436003,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uOk7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 424w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 848w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 1272w, https://substackcdn.com/image/fetch/$s_!uOk7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a47a0d4-ad7e-430f-ab6c-5cf1e06549de_1011x502.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Finally, on a particularly introspective day, I turned my gaze in the other direction, and I read the bench for the first time, and it give me chills.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;TO THOSE WHO SHALL SIT HERE REJOICING&lt;br&gt;TO THOSE WHO SHALL SIT HERE MOURNING&lt;/p&gt;&lt;p&gt;SYMPATHY AND GREETING&lt;/p&gt;&lt;p&gt;SO HAVE WE DONE IN OUR TIME&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It felt like this bench was saying:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;we have no idea what you&amp;#8217;re going through, or what your world looks like&lt;/p&gt;&lt;p&gt;you may be sitting here overflowing with joy &amp;amp; optimism &lt;/p&gt;&lt;p&gt;you may be sitting here in a pit of despair&lt;/p&gt;&lt;p&gt;know this:&lt;strong&gt; we&amp;#8217;ve felt all of these things too, and we made it through&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;#8212; 1892&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It&amp;#8217;s that last line that keeps ringing in my ear. It feels intensely comforting to me. I think because there&amp;#8217;s a tendency to think that whatever we&amp;#8217;re feeling now is new and unique, and this makes us feel alone. But the bench is saying: we know this is a good spot to contemplate, to sit with despair or to feel your joy. Even though your situation is completely different, we felt those exact same feelings, about our future, and about our past. &lt;/p&gt;&lt;p&gt;We&amp;#8217;ve been &lt;em&gt;here &lt;/em&gt;before. Physically here, and emotionally here. &lt;/p&gt;&lt;p&gt;I started thinking about the generations of people who sat on this bench, alone, on an early morning. Perhaps on their last day in town before they left. Kindred spirits. &lt;/p&gt;&lt;p&gt;I started thinking about my heroes who went to Cornell. This bench would have been here when Carl Sagan was here. I imagined him sitting at this bench, looking at the stars, maybe contemplating how to convince NASA to make the Voyager probe use its remaining energy to turn around and &lt;a href="https://en.wikipedia.org/wiki/Pale_Blue_Dot"&gt;take a picture of Earth.&lt;/a&gt; &lt;/p&gt;&lt;p&gt;I thought about Richard Feynman. This bench is older than him too. I imagined him sitting at this bench too, alone, thinking &lt;a href="https://omarshehata.substack.com/i/144258045/richard-feynman-on-explaining-technical-matters-to-the-average-person"&gt;about how we dumb things down too much for the layperson&lt;/a&gt;, and how we can do better.&lt;/p&gt;&lt;p&gt;I thought about how every single year there are hundreds of people who sit here alone. I thought about the people that haven&amp;#8217;t yet made their way up here, but who will.&lt;/p&gt;&lt;p&gt;The inscription on this bench is dated to 132 years ago. I have no idea what this spot is going to look like in 132 years from now. But I hope we&amp;#8217;ll leave something behind to remind those who come after, that no matter how amazing or terrible things might be then, either way: this is a damn good spot to think about it. &lt;/p&gt;</ns2:encoded></item><item><title>I love Scott Hanselman's social media presence</title><description>Everyone likes to hate on social media for being toxic/polarizing, but, apparently it doesn't have to be this way</description><link>https://omarshehata.substack.com/p/i-love-scott-hanselmans-social-media</link><guid isPermaLink="false">https://omarshehata.substack.com/p/i-love-scott-hanselmans-social-media</guid><dc:creator>omar</dc:creator><pubDate>Thu, 06 Jun 2024 14:54:30 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e5258d8d-fec7-419b-b767-20748a330b72_1332x673.png" length="0" type="image/jpeg"/><ns2:encoded>&lt;p&gt;I stumbled on a rare, beautiful interaction on social media. I&amp;#8217;d like to talk about it here and reflect on what I learned. &lt;/p&gt;&lt;p&gt;It starts with this scathing critique of Microsoft&amp;#8217;s new &amp;#8220;AI Recall&amp;#8221; feature:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;For those who aren&amp;#8217;t aware, Microsoft have decided to bake essentially an infostealer into base Windows OS and enable by default&lt;br&gt;&lt;br&gt;From the Microsoft FAQ: &amp;#8220;Note that Recall does not perform content moderation. It will not hide information such as passwords or financial account numbers."&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;#8212; Kevin Beaumont (&lt;a href="https://mastodon.gamedev.place/@GossiTheDog@cyberplace.social/112479978060691120"&gt;mastodon&lt;/a&gt;)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;His biggest point is that Microsoft said, &amp;#8220;don&amp;#8217;t worry, it&amp;#8217;s safe! it&amp;#8217;s all local, so an attacker would need to get physical access to your machine to steal it&amp;#8221;&lt;/p&gt;&lt;p&gt;Kevin says this gives the users a false sense of safety, because it&amp;#8217;s not true. The data is stored in a local DB on your computer. It&amp;#8217;s just a file (and files can presumably be copied/accidentally shared/you can download malware that accesses it etc).&lt;/p&gt;&lt;p&gt;At some point he brings up a TikTok of a Microsoft employee trying to convince us that it is indeed all done locally so it is safe.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HybV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HybV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 424w, https://substackcdn.com/image/fetch/$s_!HybV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 848w, https://substackcdn.com/image/fetch/$s_!HybV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 1272w, https://substackcdn.com/image/fetch/$s_!HybV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!HybV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png" width="534" height="218" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:218,&amp;quot;width&amp;quot;:534,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:126374,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HybV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 424w, https://substackcdn.com/image/fetch/$s_!HybV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 848w, https://substackcdn.com/image/fetch/$s_!HybV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 1272w, https://substackcdn.com/image/fetch/$s_!HybV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F161faec2-00a5-4a0f-bb18-f31dbde50977_534x218.png 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://mastodon.gamedev.place/@GossiTheDog@cyberplace.social/112493241681204311"&gt;mastodon thread&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;At this point I notice that this is a video of Scott Hanselman. I know (of) that guy! He&amp;#8217;s usually a voice of reason. So I was curious if he had a response to being called out like this. &lt;/p&gt;&lt;p&gt;I scroll down and I find it (emphasis mine):&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I don&amp;#8217;t work on the project but I find the NPU tech and the open SDKs behind it (and onyx runtime) interesting. &lt;strong&gt;My opinion is it should be not just opt-in but something you download explicitly and install if you want it&lt;/strong&gt;. Similar to RescueTime and TimeSnapper and AugmenD and other apps that have done this stuff for years (using OCR). This should be as secure as your browser history, encrypted at rest, non roaming, etc.&lt;/p&gt;&lt;p&gt;&amp;#8212; Scott Hanselman (&lt;a href="https://mastodon.gamedev.place/@shanselman@hachyderm.io/112497530969484139"&gt;mastodon&lt;/a&gt;)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Someone tells Scott they appreciate him answering honestly. He says:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;We have nothing if we don&amp;#8217;t have integrity&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Someone tells him, yeah but we don&amp;#8217;t trust microsoft, they&amp;#8217;ve done so many shitty things to users in the past!!! And Scott says:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Agreed, sometimes we are emptying the ocean with a teaspoon. I will use my level privilege to advocate for the user as long as I&amp;#8217;m here.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;wow!&lt;/p&gt;&lt;h1&gt;It could always be like this&lt;/h1&gt;&lt;p&gt;Scott could have responded with something like &amp;#8220;first of all, you&amp;#8217;re taking my words out of context. I did NOT say xyz&amp;#8221;. And he&amp;#8217;d be right. But I see this kind of interaction all the time, and it&amp;#8217;s rarely productive.&lt;/p&gt;&lt;p&gt;It doesn&amp;#8217;t have to be this way. &lt;/p&gt;&lt;p&gt;Scott instead chooses to focus on the common ground. Scott doesn&amp;#8217;t take this criticism personally. That&amp;#8217;s not the point. The point is that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Kevin cares about user privacy, and not misleading the public&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Scott cares about this too&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;They are on the same side &lt;em&gt;&lt;strong&gt;on this point&lt;/strong&gt;&lt;/em&gt;. Scott is defending the Microsoft feature, because he thinks it IS potentially genuinely useful. Scott sees a world where things can be better, where we can have the cool AI features, AND we can respect user&amp;#8217;s data security and agency (making it opt-in). &lt;/p&gt;&lt;p&gt;Scott probably feels this more tangibly than others, being on the inside, being in the room. He has probably seen decisions made where, it could have been worse. He&amp;#8217;s seen people make the right decisions. He&amp;#8217;s seen engineers change their mind &amp;amp; implementation. He has tangible optimism.&lt;/p&gt;&lt;p&gt;I just love the way he talks, with this rare honesty &amp;amp; transparency that I didn&amp;#8217;t even realize was an option, for me, as a software engineer at Big Tech. It feels like listening to a real person talk.&lt;/p&gt;&lt;p&gt;I think this is what I appreciate most about social media, when it work well. &lt;/p&gt;&lt;p&gt;I read this advice a while back and I think it completely changed my social media experience:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I wish people arguing on Twitter remembered that 100x more people read the exchange than the people involved in it. &lt;/p&gt;&lt;p&gt;Don't say: "you're dumb, not worth arguing with". Just explain why they're wrong. It doesn't matter if they won't get it. Address the audience, not them&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I see a lot of arguments where I am still trying to form an opinion, and people refuse to engage, and I don&amp;#8217;t understand why the bad thing is bad. &lt;/p&gt;&lt;p&gt;I know it&amp;#8217;s hard to argue with people who are doing it in bad faith. But remember, it&amp;#8217;s not the goal. And it&amp;#8217;s not about you either. I&amp;#8217;m not here to win arguments, I&amp;#8217;m here to figure out (1) what steps can we take to craft a better world (2) if people are opposed to my solutions, what are their reasons? In this way, anyone mad or angry at me, is helping me shape this vision. &lt;/p&gt;&lt;p&gt;It can always collaborative.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</ns2:encoded></item><item><title>My favorite 1980's Canadian TV show: Bits and Bytes</title><description>Reflections on whatever I'm thinking about that week (the web, culture, computer graphics, math etc)</description><link>https://omarshehata.substack.com/p/my-favorite-1980s-canadian-tv-show</link><guid isPermaLink="false">https://omarshehata.substack.com/p/my-favorite-1980s-canadian-tv-show</guid><dc:creator>omar</dc:creator><pubDate>Sat, 11 May 2024 23:11:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9be822fa-a67f-4c7f-bd76-0463c72a211d_250x172.gif" length="0" type="image/jpeg"/><ns2:encoded>&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C6Rg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C6Rg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 424w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 848w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 1272w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!C6Rg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif" width="250" height="172" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:false,&amp;quot;imageSize&amp;quot;:&amp;quot;normal&amp;quot;,&amp;quot;height&amp;quot;:172,&amp;quot;width&amp;quot;:250,&amp;quot;resizeWidth&amp;quot;:250,&amp;quot;bytes&amp;quot;:870844,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/gif&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!C6Rg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 424w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 848w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 1272w, https://substackcdn.com/image/fetch/$s_!C6Rg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F983e62a4-a589-4abe-bd0e-2444ad0e120c_250x172.gif 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&lt;a href="https://www.youtube.com/@bitsandbytestvo"&gt;https://www.youtube.com/@bitsandbytestvo&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I love this adorable little TV show so much. Old TV is just so quaint: it&amp;#8217;s much slower paced than today&amp;#8217;s media, there&amp;#8217;s less jump cuts, and the screen transitions and animations are often quirky. There&amp;#8217;s not as much industry-wide &amp;#8220;best practices&amp;#8221;, so there&amp;#8217;s a much greater variance in quality, and thus variety of unique little gems.&lt;/p&gt;&lt;p&gt;But I think the main reason I love it so much is because, compared to today: &lt;strong&gt;they have a MUCH higher bar of what they think the layperson is capable of understanding &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I&amp;#8217;d like to show you some of my favorite snippets here, starting with the intro:&lt;/p&gt;&lt;div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&amp;quot;mediaUploadId&amp;quot;:&amp;quot;b87e39e6-8194-4802-8672-54cf43a7a456&amp;quot;,&amp;quot;duration&amp;quot;:null}"&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;bits and bytes of information, tuuuuurning darkness, to liiiiiiiiiiiiiiight&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Luba Goy then tells us that we&amp;#8217;re going to learn how to USE a computer. &lt;strong&gt;This is important, this is NOT a TV show about how computers work&lt;/strong&gt;. It&amp;#8217;s NOT meant to inspire kids to pursue engineering or whatever. This is for the average person who just wants to use a computer to do every day things, like their taxes.&lt;/p&gt;&lt;p&gt;It is very clear who the audience is supposed to be, because we have Billy Van representing &lt;em&gt;&amp;#8220;the average person who knows nothing about computers but wants to learn&amp;#8221;&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;I love watching his first reaction to a computer (it&amp;#8217;s clear he&amp;#8217;s never used one before!)&lt;/p&gt;&lt;div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&amp;quot;mediaUploadId&amp;quot;:&amp;quot;297003b2-be09-4baf-bed7-8f317f322c22&amp;quot;,&amp;quot;duration&amp;quot;:null}"&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;I&amp;#8217;m afraid computers don&amp;#8217;t do anything on their own, you have to program them!&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Later, Luba has to patiently explain to Billy that he has to press &amp;#8220;enter&amp;#8221; and what that means. She even has a handy little infographic:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vSf-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vSf-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 424w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 848w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 1272w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!vSf-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png" width="819" height="609" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/a8558689-a538-4784-8f89-855cb8b9505e_819x609.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:609,&amp;quot;width&amp;quot;:819,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:570202,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vSf-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 424w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 848w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 1272w, https://substackcdn.com/image/fetch/$s_!vSf-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8558689-a538-4784-8f89-855cb8b9505e_819x609.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;&amp;#8220;Return&amp;#8221; means &amp;#8220;over to you, computer!&amp;#8221; like a walkie talkie! &lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I&amp;#8217;m belaboring this point because I want to make it very clear that this is meant to educate at a very basic level of how to use a computer. Imagine teaching your grandma how to use her smart TV. This is kind of how Luba talks to Billy. &lt;/p&gt;&lt;p&gt;And yet, they do NOT talk down to their audience. They do not dumb things down. They explain things in a surprising amount of detail. &lt;strong&gt;The explanations are concise &amp;amp; straightforward, but NOT dumbed down. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For example, in this episode they load a video game from a cassette tape. Billy asks this wonderful question:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;[how is it possible that] all this [non-sound] information, words, letters, and pictures, can be contained in an &lt;em&gt;audio &lt;/em&gt;cassette tape?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;A bad answer to this question would say: &amp;#8220;the cassette tape contains the data for the video game, the computer knows how to decode it. You press this button here, load it like this, then you press that button, etc&amp;#8221;. This isn&amp;#8217;t wrong, and it may in fact contain a lot of detail, but &lt;strong&gt;it doesn&amp;#8217;t tell me anything about how this system works.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;More importantly: it doesn&amp;#8217;t help me interact with it better. It doesn&amp;#8217;t allow me to make predictions or develop a model of it in my mind (which is very important for when things go wrong, or when I want to do something outside the scope of instructions). &lt;/p&gt;&lt;p&gt;Let&amp;#8217;s see how Luba answers this question:&lt;/p&gt;&lt;div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&amp;quot;mediaUploadId&amp;quot;:&amp;quot;39ad6e70-772b-4e4c-b12d-ce2503f82403&amp;quot;,&amp;quot;duration&amp;quot;:null}"&gt;&lt;/div&gt;&lt;p&gt;She has him play the tape (which contains machine code for a video game) on an  audio cassette player. To Billy&amp;#8217;s surprise, it works just fine, it just produces an awful noise!&lt;/p&gt;&lt;p&gt;They then proceed to explain what &amp;#8220;binary code&amp;#8221; is: that we use a series of &amp;#8220;on&amp;#8221; and &amp;#8220;off&amp;#8221; switches, and we can choose to make these sequences represent anything: numbers, letters, or commands.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!foYY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!foYY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 424w, https://substackcdn.com/image/fetch/$s_!foYY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 848w, https://substackcdn.com/image/fetch/$s_!foYY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 1272w, https://substackcdn.com/image/fetch/$s_!foYY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!foYY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png" width="831" height="543" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:543,&amp;quot;width&amp;quot;:831,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:541971,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!foYY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 424w, https://substackcdn.com/image/fetch/$s_!foYY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 848w, https://substackcdn.com/image/fetch/$s_!foYY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 1272w, https://substackcdn.com/image/fetch/$s_!foYY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b5701c4-336d-432d-b7c3-514d4af86dc6_831x543.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;(&lt;a href="https://www.youtube.com/watch?v=AdF2uk-EscE"&gt;here's the 2 min segment where they explain what binary code&lt;/a&gt; is, if you&amp;#8217;re curious)&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;I think this demonstration of playing &amp;#8220;text&amp;#8221; over an audio player is amazing. I&amp;#8217;m drawn to it because this is how I personally developed my own fundamental understanding of what data on a computer &lt;em&gt;is&lt;/em&gt;, and I think it&amp;#8217;s beautiful that this is also how we explain it to the layperson. &lt;/p&gt;&lt;p&gt;There is nothing inherently special about text vs images vs audio. ALL of them are stored using the same primitives (0&amp;#8217;s and 1&amp;#8217;s). They have no inherent meaning. They get their meaning from how you choose to decode them. &lt;/p&gt;&lt;p&gt;You store the number 65 in binary. That might mean the letter &amp;#8220;A&amp;#8221; if this is an ASCII text document. It might be a musical note in MIDI. Or something else entirely. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;What does the layperson get out of this?&lt;/strong&gt; They have a basic, but useful model of how the machine works. I bet you could use this to deduce something like: how would you come up with a basic encryption system? (you could just encode data in a custom way, and not tell anyone!)&lt;/p&gt;&lt;p&gt;I really do believe this matters day to day. It matters when the computer behaves in unexpected ways, or when you think about what is possible in the future. Or even simply, to give yourself a fighting chance to tell what is &amp;#8220;easy&amp;#8221; and what is &amp;#8220;hard&amp;#8221; when working with the people who program these things. &lt;/p&gt;&lt;p&gt;Here&amp;#8217;s an example where Billy asks &amp;#8220;why is the computer so slow?&amp;#8221; and Luba clarifies exactly why it&amp;#8217;s slow:&lt;/p&gt;&lt;div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&amp;quot;mediaUploadId&amp;quot;:&amp;quot;b23b4238-b469-419b-9ca6-ff4de52a83d1&amp;quot;,&amp;quot;duration&amp;quot;:null}"&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;&amp;#8220;[these computers] ARE fast, it&amp;#8217;s the cassette that&amp;#8217;s slow!&amp;#8221;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Does the modern layperson know why their computer is slow? Is this web page sluggish because the internet is bad, or because the CPU is old, or because it&amp;#8217;s just a janky website? &lt;/p&gt;&lt;p&gt;&lt;strong&gt;I don&amp;#8217;t think this is too much for the average person to understand&lt;/strong&gt;. I think the average person is perfectly capable of dealing with complexity, when it matters to their day to day lives.&lt;/p&gt;&lt;p&gt;Recently, Chrome added &amp;#8220;memory usage&amp;#8221; info on each tab. I think this is great.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0WrD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0WrD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 424w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 848w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 1272w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!0WrD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png" width="346" height="174" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/a9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:174,&amp;quot;width&amp;quot;:346,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:14959,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0WrD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 424w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 848w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 1272w, https://substackcdn.com/image/fetch/$s_!0WrD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9fd19ad-d3b3-4eff-b4fe-2293126f4f1c_346x174.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;Chrome showing memory utilization for each tab on hover is an excellent feature &amp;#8212; awareness of resource consumption is necessary to care about it.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;em&gt;John Carmack, from: &lt;a href="https://twitter.com/ID_AA_Carmack/status/1727048755881611268"&gt;https://twitter.com/ID_AA_Carmack/status/1727048755881611268&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h1&gt;Richard Feynman on explaining technical matters to the average person&lt;/h1&gt;&lt;p&gt;In &amp;#8220;The Meaning of it All&amp;#8221; Feynman talks about how this belief that the average person is dumb is a &amp;#8220;dangerous idea&amp;#8221;. He expresses his frustration with people who write simplified explanations of technical matters because they don&amp;#8217;t think the layperson is capable of, nor interested in, understanding how things work.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UFWi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UFWi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 424w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 848w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 1272w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!UFWi!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png" width="1200" height="651.7857142857143" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/f8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:false,&amp;quot;imageSize&amp;quot;:&amp;quot;large&amp;quot;,&amp;quot;height&amp;quot;:730,&amp;quot;width&amp;quot;:1344,&amp;quot;resizeWidth&amp;quot;:1200,&amp;quot;bytes&amp;quot;:1286322,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UFWi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 424w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 848w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 1272w, https://substackcdn.com/image/fetch/$s_!UFWi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8c3aa7f-15dc-4c93-a722-88f7548a58db_1344x730.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;page 88, or &lt;a href="https://antilogicalism.com/wp-content/uploads/2018/11/meaning-of-it-all.pdf"&gt;38 in this PDF&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Feynman gives us a really good rule of thumb to evaluate scientific writing: he says it sucks when even HE as an expert can&amp;#8217;t tell what they&amp;#8217;re talking about&lt;/p&gt;&lt;p&gt;I think &amp;#8220;Bits and Bytes&amp;#8221; passes that bar for me. When they tell Billy Van to think of a computer as &amp;#8220;a lot of little Aristotle&amp;#8217;s turning on and off&amp;#8221;, I know it&amp;#8217;s a silly metaphor, and &lt;strong&gt;I know it&amp;#8217;s simplified, but I recognize the useful truth it gives the viewer&lt;/strong&gt;. It&amp;#8217;s not fundamentally different from the mental model the expert has in their mind. This metaphor helps the viewer understand how computers are simultaneously &amp;#8220;dumb&amp;#8221; (because they really only do very basic operations) and yet how you can scaffold layers of that to make something smart. &lt;/p&gt;&lt;p&gt;I think Feynman would like this show. I think it&amp;#8217;s a combination of:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;There really are no &amp;#8220;stupid questions&amp;#8221; here. If the question is that simple &amp;amp; basic, they&amp;#8217;ll just say the answer. More often a &amp;#8220;silly question&amp;#8221; reveals something fundamental and profound when taken seriously&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;There&amp;#8217;s no &amp;#8220;magic&amp;#8221; or &amp;#8220;black box&amp;#8221; explanations. There&amp;#8217;s no hand waving. They don&amp;#8217;t have time to explain everything, but they will try to explain it honestly, OR they will say &amp;#8220;that&amp;#8217;s out of scope, future episode&amp;#8221;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;They encourage you to &amp;#8220;peek behind the curtain&amp;#8221;. They reward curiosity, even for questions that seem irrelevant &lt;em&gt;(like: &amp;#8220;why is the power button on the back of the computer&amp;#8221; or &amp;#8220;why does it say I have 31k of memory, when you said this computer has 32k?)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h1&gt;On how we should explain things today&lt;/h1&gt;&lt;p&gt;A message to my future self:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;resist the urge to dumb things down when explaining complex technical matters&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;if you&amp;#8217;re struggling to distill down the essential details, just start with what YOUR mental model is. Think about how you, as an expert, predict or debug this system. Then come up with a metaphor to capture that model&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;(this is the same principle behind &lt;a href="https://mastodon.gamedev.place/@omarshehata/112389823366636715"&gt;teaching with psuedocode&lt;/a&gt;, we remove unnecessary details &amp;amp; keep the essential model)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The average person in today&amp;#8217;s society is capable of understanding complex technical matters when they are sufficiently motivated&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;If anyone tells you otherwise, it&amp;#8217;s almost certainly just a skill issue (you&amp;#8217;re not trying hard enough to explain it well! or you&amp;#8217;re explaining it at the wrong level of abstraction, or the person doesn&amp;#8217;t see why it matters to them. It&amp;#8217;s on you to figure that out. if you can&amp;#8217;t spell it out, maybe they were right in thinking it doesn&amp;#8217;t matter)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I struggle with the question of: how much SHOULD I try to explain about the &amp;#8220;behind the scenes&amp;#8221; to the layperson? How much should we abstract away, to use without understanding? Do I need to know the inner workings of my car, for example? &lt;/p&gt;&lt;p&gt;My rule of thumb is: if it&amp;#8217;s something I use a lot / rely on, I want to at least have (1) a model of how it works (2) some basic ways to verify it, so I can check my own understanding from time to time. For me, things that fall under this category are: my car, the plumbing and HVAC of my house, and the economy &amp;amp; political system in which I live. &lt;/p&gt;&lt;p&gt;Ultimately, it&amp;#8217;s a tough balance, it&amp;#8217;s hard to always get it right, the answer is always kind of &amp;#8220;it depends&amp;#8221;, but I think it&amp;#8217;s worth trying, and I think we can tell when it&amp;#8217;s done right. And I think Bits and Bytes is one good example of that.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="button-wrapper" data-attrs="{&amp;quot;url&amp;quot;:&amp;quot;https://omarshehata.substack.com/subscribe?&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;Subscribe now&amp;quot;,&amp;quot;action&amp;quot;:null,&amp;quot;class&amp;quot;:null}" data-component-name="ButtonCreateButton"&gt;&lt;a class="button primary" href="https://omarshehata.substack.com/subscribe?"&gt;&lt;span&gt;Subscribe now&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;</ns2:encoded></item><item><title>Presentation Night - Feb 7 - Recap</title><description>Highlights from the first Presentation Night</description><link>https://omarshehata.substack.com/p/presentation-night-feb-7-recap</link><guid isPermaLink="false">https://omarshehata.substack.com/p/presentation-night-feb-7-recap</guid><dc:creator>omar</dc:creator><pubDate>Sun, 02 Apr 2023 17:47:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg" length="0" type="image/jpeg"/><ns2:encoded>&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yY1D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset image2-full-screen"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yY1D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!yY1D!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:false,&amp;quot;imageSize&amp;quot;:&amp;quot;full&amp;quot;,&amp;quot;height&amp;quot;:543,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:647345,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:false,&amp;quot;topImage&amp;quot;:true,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-fullscreen" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yY1D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yY1D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93560fcc-b264-4461-980a-15e45e986a23_2560x954.jpeg 1456w" sizes="100vw" fetchpriority="high"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;figcaption class="image-caption"&gt;Jonathan &amp;amp; Lesley from Story House Ithaca kicking off presentation night to a full house, at the Soil Factory&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&amp;#8220;Presentation Night&amp;#8221; is an event I hosted with &lt;a href="https://www.storyhouseithaca.org/event-details/presentation-night"&gt;Story House Ithaca&lt;/a&gt; on Feb 7th. It was super fun, we got a huge turnout (65 people!) and &lt;a href="https://www.storyhouseithaca.org/event-details/presentation-night-4"&gt;we&amp;#8217;re doing it again Tuesday June 6th.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This event is kind of difficult to describe so I wanted to write up this recap about how it went. I hope you find this helpful, if you&amp;#8217;re curious about attending an upcoming one, pitching a talk, or hosting your own version of it!&lt;/p&gt;&lt;h3&gt;What is Presentation Night?&lt;/h3&gt;&lt;p&gt;Five people give 5 minute talks about anything. &lt;/p&gt;&lt;p&gt;The way I pitch this to people is: you should give a talk &amp;#8220;&lt;strong&gt;anything that brings you joy &amp;amp; delight&lt;/strong&gt;, and that you think is worth sharing&amp;#8221;.&lt;/p&gt;&lt;p&gt;We advertise it as &amp;#8220;an evening of talks by non-experts&amp;#8221;. You&amp;#8217;re encouraged to pick a topic you &lt;em&gt;don&amp;#8217;t &lt;/em&gt;know a lot about, perhaps one you&amp;#8217;ve always wanted to understand, and share what you learned.&lt;/p&gt;&lt;p&gt;What this event is really about for me:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning is fun &amp;#8212;&lt;/strong&gt; &amp;amp; it&amp;#8217;s generally more fun with others.&lt;strong&gt; &lt;/strong&gt;This is a space for you to share cool stuff you&amp;#8217;ve just learned, and learn from others. Having this recurring event helps me a lot in staying curious as I go through the world. It reminds me that it&amp;#8217;s worth pursuing because there are others who do care about whatever has piqued my interest.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Joy is infectious &amp;#8212; &lt;/strong&gt;watching someone really excitedly talk about their interests is incredibly rejuvenating. It makes me want to pick up things in my own life that bring me joy just for its own sake. This was a common sentiment with people I spoke to after the event.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;People are interesting&lt;/strong&gt; &lt;strong&gt;&amp;#8212; &lt;/strong&gt;I&amp;#8217;ve met a lot of people here in Ithaca who are really cool and I just want to hear them talk about their life, how they spend their time, or just something cool they want to share. It&amp;#8217;s typically not very polite in a social hang to just start lecturing at people, but presentation night is exactly the space for that! &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expanding your world&lt;/strong&gt; &lt;strong&gt;&amp;#8212; &lt;/strong&gt;because the talks are only 5 min it&amp;#8217;s easy to sit through even if you have no interest in the topic. And sometimes, you might be surprised to find that something resonated with you in a topic you&amp;#8217;d never thought was  worth exploring!&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To me the only really important rule is that it should be something you care a lot about. The talks are usually lighthearted but can be about something serious. It can even be about your work. As long as it&amp;#8217;s something that (1) matters a lot to you (2) you think other people should hear it.            &lt;/p&gt;&lt;h3&gt;How it went&lt;/h3&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9qhC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9qhC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!9qhC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg" width="1456" height="1092" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1092,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:487751,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9qhC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9qhC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d7f569a-6f89-4daf-819a-cea755a30f5c_4032x3024.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Sander gave a talk on &lt;strong&gt;&amp;#8220;What is Fermentation, or, Why Isn&amp;#8217;t Sourdough Alcoholic?&amp;#8221; &lt;/strong&gt;with all hand-drawn slides.&lt;/p&gt;&lt;p&gt;It was inspired by this question of&amp;#8230;if bread is fermented in a similar process to how you make beer, why isn&amp;#8217;t there alcohol in bread? It led him down this rabbit hole to find that the answer is, apparently, bread DOES have alcohol! Kind of.&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Sfpe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Sfpe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 424w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 848w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 1272w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Sfpe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png" width="798" height="598" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/a07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:598,&amp;quot;width&amp;quot;:798,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:345725,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Sfpe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 424w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 848w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 1272w, https://substackcdn.com/image/fetch/$s_!Sfpe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07e1eb6-3239-4e8d-821c-b8ae6c4dcb06_798x598.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;My favorite part of this was that apparently during the prohibition, in 1926 there was a serious study to determine the alcohol content of bread and it found that it exceeded the amount set by the prohibition statute! &lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pOxw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pOxw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 424w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 848w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 1272w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!pOxw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png" width="796" height="601" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:601,&amp;quot;width&amp;quot;:796,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:353298,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pOxw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 424w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 848w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 1272w, https://substackcdn.com/image/fetch/$s_!pOxw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F991b69f0-c9b8-44d9-a860-18d79d65be7d_796x601.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In the Q&amp;amp;A after, someone in the audience mentioned a story about a high school kid who once tried to eat enough bread to get drunk (the consensus here appears to be that you&amp;#8217;ll get sick from the bread way before you can ever get drunk from it&amp;#8230;)&lt;/p&gt;&lt;p&gt;Naman told this funny story about &lt;a href="https://historyofislam.com/lives-that-matter/tipu-sultan-his-connection-to-the-american-national-anthem/"&gt;how a specific verse in the American national anthem was inspired by an Indian general&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Frances gave a talk about idioms and their origins. This was kind of a game where the audience would see a picture and had to guess the saying or phrase inspired by it. For example:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cb17!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cb17!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 424w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 848w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 1272w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Cb17!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png" width="985" height="461" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/b4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:461,&amp;quot;width&amp;quot;:985,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:533168,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/png&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cb17!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 424w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 848w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 1272w, https://substackcdn.com/image/fetch/$s_!Cb17!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c07959-83e6-4dc6-9747-34086ea55dc7_985x461.png 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The correct answer here is &amp;#8220;white elephant&amp;#8221;, and the reason we call them &amp;#8220;white elephant gifts&amp;#8221; is because of an old story about a king who would gift people he didn&amp;#8217;t like a white elephant. White elephants were rare and treasured, so they were expensive, but because they were rare, you couldn&amp;#8217;t kill them for food, couldn&amp;#8217;t sell them without permission from the king etc. So you were just kind of stuck taking care of this expensive &amp;#8220;gift&amp;#8221; !&lt;/p&gt;&lt;p&gt;We had a few breaks in between speakers where people mingled:&lt;/p&gt;&lt;div class="captioned-image-container"&gt;&lt;figure&gt;&lt;a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ml1Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg" data-component-name="Image2ToDOM"&gt;&lt;div class="image2-inset"&gt;&lt;picture&gt;&lt;source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 1456w" sizes="100vw"&gt;&lt;img src="https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg" width="1456" height="1092" data-attrs="{&amp;quot;src&amp;quot;:&amp;quot;https://substack-post-media.s3.amazonaws.com/public/images/0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg&amp;quot;,&amp;quot;srcNoWatermark&amp;quot;:null,&amp;quot;fullscreen&amp;quot;:null,&amp;quot;imageSize&amp;quot;:null,&amp;quot;height&amp;quot;:1092,&amp;quot;width&amp;quot;:1456,&amp;quot;resizeWidth&amp;quot;:null,&amp;quot;bytes&amp;quot;:919810,&amp;quot;alt&amp;quot;:null,&amp;quot;title&amp;quot;:null,&amp;quot;type&amp;quot;:&amp;quot;image/jpeg&amp;quot;,&amp;quot;href&amp;quot;:null,&amp;quot;belowTheFold&amp;quot;:true,&amp;quot;topImage&amp;quot;:false,&amp;quot;internalRedirect&amp;quot;:null,&amp;quot;isProcessing&amp;quot;:false,&amp;quot;align&amp;quot;:null,&amp;quot;offset&amp;quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ml1Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0259ae57-fc45-4148-a236-1ef11e959ede_2560x1920.jpeg 1456w" sizes="100vw" loading="lazy"&gt;&lt;/picture&gt;&lt;div class="image-link-expand"&gt;&lt;div class="pencraft pc-display-flex pc-gap-8 pc-reset"&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"&gt;&lt;svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"&gt;&lt;g&gt;&lt;title&gt;&lt;/title&gt;&lt;path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/button&gt;&lt;button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"&gt;&lt;polyline points="15 3 21 3 21 9"&gt;&lt;/polyline&gt;&lt;polyline points="9 21 3 21 3 15"&gt;&lt;/polyline&gt;&lt;line x1="21" x2="14" y1="3" y2="10"&gt;&lt;/line&gt;&lt;line x1="3" x2="10" y1="21" y2="14"&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Finally, I gave a talk about &amp;#8220;How do we know what we know?&amp;#8221; where I was trying to grapple with this idea that we take for granted a lot of knowledge about the world, and that it&amp;#8217;s worth asking &amp;#8220;how do we actually know that?&amp;#8221; My example was &amp;#8220;how do we know dinosaurs looked like that?&amp;#8221; (because we have their bones, but we don&amp;#8217;t know if they were furry or scaly etc. &lt;a href="https://www.buzzfeednews.com/article/natashaumer/dinosaur-animals"&gt;Here&amp;#8217;s a fun series of pictures&lt;/a&gt; about what a lot of modern animals would be depicted if we only ever saw their bones).&lt;/p&gt;&lt;h3&gt;Finding community &amp;amp; private presentation nights&lt;/h3&gt;&lt;p&gt;Ultimately a big part of doing all this is to connect with other people &amp;amp; share in each other&amp;#8217;s journeys of learning and growth. If a talk resonated with you I encourage you to reach out, either in person at the event or shoot them an email afterwards.&lt;/p&gt;&lt;p&gt;Story House Ithaca has created a FB group for post-event discussion here:&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.facebook.com/groups/745568260501449"&gt;https://www.facebook.com/groups/745568260501449 &lt;/a&gt;&lt;/p&gt;&lt;p&gt;I think organizing a private variant of this with friends is a wonderful thing to do because then it creates this space where you can be vulnerable, and maybe share something you&amp;#8217;re still trying to figure out, and find support in that.&lt;/p&gt;&lt;p&gt;If this is something you&amp;#8217;ve done or are thinking of doing and want to share how it went, please reach out! I&amp;#8217;d love to hear about it.&lt;/p&gt;&lt;p&gt;&lt;a href="https://omarshehata.me/"&gt;https://omarshehata.me/&lt;/a&gt;&lt;/p&gt;</ns2:encoded></item></channel>
</rss>
