<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcus huang</title>
    <description>The latest articles on DEV Community by Marcus huang (@marcushuang).</description>
    <link>https://dev.to/marcushuang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4203312%2F08efe62b-3044-40c6-b51d-96eb8e7d3dc3.png</url>
      <title>DEV Community: Marcus huang</title>
      <link>https://dev.to/marcushuang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcushuang"/>
    <language>en</language>
    <item>
      <title>Generating Hero Images, Icons and OG Cards for a Side Project with Nano Banana 2.1</title>
      <dc:creator>Marcus huang</dc:creator>
      <pubDate>Sat, 24 Oct 2026 01:21:39 +0000</pubDate>
      <link>https://dev.to/marcushuang/generating-hero-images-icons-and-og-cards-for-a-side-project-with-nano-banana-21-384h</link>
      <guid>https://dev.to/marcushuang/generating-hero-images-icons-and-og-cards-for-a-side-project-with-nano-banana-21-384h</guid>
      <description>&lt;p&gt;Every side project hits the same wall right before launch: the code works, but the landing page has no images. Here is the workflow I use to generate a consistent asset set with &lt;a href="https://nanobanana21pro.com/" rel="noopener noreferrer"&gt;nanobanana21pro.com&lt;/a&gt;, an independent third-party web app built on Google's Nano Banana image models.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: nanobanana21pro.com is not a Google product and not Google AI Studio. It is a separate service, not affiliated with or endorsed by Google. Writing prompts is free; generating images uses credits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Write an asset spec before any prompt
&lt;/h2&gt;

&lt;p&gt;Treat images like any other dependency. I keep a small spec file in the repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;palette&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#0F172A"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#38BDF8"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#F8FAFC"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;soft&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;3D&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;clay,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rounded&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;shapes,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;studio&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;lighting"&lt;/span&gt;
&lt;span class="na"&gt;assets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hero&lt;/span&gt;
    &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;16:9"&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2K&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;feature-icons&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1:1"&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1K&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;og-card&lt;/span&gt;
    &lt;span class="na"&gt;ratio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.91:1&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(closest&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;available)"&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1K&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is to reuse the same style string in every prompt, so the set looks like it belongs together.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Generate the hero first
&lt;/h2&gt;

&lt;p&gt;The hero sets the visual language. Example prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Soft 3D clay illustration of a small rocket made of stacked code brackets,
launching from a laptop keyboard, navy background (#0F172A),
sky blue accents (#38BDF8), studio lighting, lots of empty space on the left
for a headline. No text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ask for empty space where your headline will sit.&lt;/li&gt;
&lt;li&gt;Say "No text" when the HTML will carry the copy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Use the hero as a reference for everything else
&lt;/h2&gt;

&lt;p&gt;This is where reference editing pays off. Nano Banana 2.1 accepts up to 14 reference images, so I attach the approved hero and give it a role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use the reference image only for style, color palette and lighting.
Create a single soft 3D clay icon of a padlock on a plain #F8FAFC background,
centered, 1:1. No text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeat for each feature icon (padlock, lightning bolt, chart). Because the hero is the style reference, the icons stay on-brand.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. OG card with real text
&lt;/h2&gt;

&lt;p&gt;For social preview cards I do want text in the image, and this is an area where the 2.1 model is strong at legible lettering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use the reference image for style and palette.
Wide social preview card, the words SHIPKIT in bold white letters on the left,
the tagline "Deploy in one command" below it in smaller sky blue letters,
the clay rocket on the right.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep text short and quote it exactly. Check every letter before you ship it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Budget the run
&lt;/h2&gt;

&lt;p&gt;The generator shows a credit quote before you submit. On Nano Banana 2.1:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Credits per image&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1K&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2K&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4K&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;My set above (one 2K hero, three 1K icons, one 1K OG card, plus a few retries) fits in a small credit pack. One-time packs start at $2.99, and monthly plans are $18.99/mo and $44.99/mo. Batch size multiplies the cost, so explore at 1K.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>design</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building a Weighted-Random Birth Simulator on an Open-Source Engine</title>
      <dc:creator>Marcus huang</dc:creator>
      <pubDate>Fri, 23 Oct 2026 19:19:00 +0000</pubDate>
      <link>https://dev.to/marcushuang/building-a-weighted-random-birth-simulator-on-an-open-source-engine-535f</link>
      <guid>https://dev.to/marcushuang/building-a-weighted-random-birth-simulator-on-an-open-source-engine-535f</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I made 1in8billion.live. It's an independent, unofficial fan-made game inspired by "1 in 8 Billion" and isn't affiliated with 1in8b.life. I built it on top of the MIT-licensed open-source born-somewhere engine, which I didn't write.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is a write-up of the design ideas behind &lt;strong&gt;1 in 8 Billion – Free Life Simulator&lt;/strong&gt;, my browser game where you're born in a random country and live one life from birth to death. It covers the general patterns: weighted sampling, data-driven events, local saves and i18n. The code snippets are simplified illustrations of each pattern, not the production source.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Weighted random selection
&lt;/h3&gt;

&lt;p&gt;The core mechanic is a draw over 172 countries. A uniform &lt;code&gt;Math.random()&lt;/code&gt; pick would be wrong, because Tuvalu shouldn't come up as often as India. The game weights the draw by &lt;strong&gt;annual births&lt;/strong&gt;, and the homepage shows the resulting shares: India around 17.6%, China around 6.7%, Nigeria around 5.7%, and so on.&lt;/p&gt;

&lt;p&gt;The standard way to do this is cumulative-weight sampling:&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;function&lt;/span&gt; &lt;span class="nf"&gt;weightedPick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// items: [{ id: "IN", weight: 23000000 }, ...]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weight&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&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="nx"&gt;total&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;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;r&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;weight&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;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&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;item&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;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;items&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For 172 entries a linear scan is plenty fast. If you were sampling millions of times, you'd precompute a prefix-sum array and binary search it, or use the alias method for O(1) draws.&lt;/p&gt;

&lt;p&gt;I also added a &lt;strong&gt;population mode&lt;/strong&gt;, which swaps birth weights for population weights. That's a nice example of keeping the sampling function generic and passing in a different weight vector.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Data-driven life events
&lt;/h3&gt;

&lt;p&gt;Each country carries real indicators: &lt;strong&gt;life expectancy, infant mortality, under-5 mortality and GDP per capita (PPP)&lt;/strong&gt;. A simple way to turn these into gameplay is a yearly hazard. Each simulated year, compute a probability of death (and of other events) from the country's stats and the character's age, then roll for it. Infant and under-5 mortality cover the early years, and life expectancy calibrates the curve for the rest of the life.&lt;/p&gt;

&lt;p&gt;Choices sit on top of this. At turning points the player picks an action, or &lt;strong&gt;auto mode&lt;/strong&gt; picks one, and the result nudges stats like health, happiness, knowledge and social standing. The game shows these as 0–100 meters along with net assets in PPP dollars.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Batch simulation
&lt;/h3&gt;

&lt;p&gt;Once a single life is a pure-ish function of &lt;code&gt;(country, seed, choices)&lt;/code&gt;, running many is easy. The game's &lt;strong&gt;Lab&lt;/strong&gt; runs lives in bulk and summarizes the results. If you build something similar, keep the simulation step free of DOM access so you can move it to a Web Worker without changing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. No-backend saves with localStorage
&lt;/h3&gt;

&lt;p&gt;There's no signup. Progress and past lives are saved &lt;strong&gt;in the browser on the device&lt;/strong&gt;, and the site tells players plainly that clearing site storage removes them and that there's no cloud sync. The usual pattern:&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;KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lives:v1&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;load&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;KEY&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="s2"&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;save&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lives&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lives&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version your keys, cap the history, and wrap &lt;code&gt;setItem&lt;/code&gt; in try/catch, because storage quotas and private-browsing modes can throw.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. i18n across six locales
&lt;/h3&gt;

&lt;p&gt;The UI ships in &lt;strong&gt;EN, DE, ES, FR, PT-BR and ZH-CN&lt;/strong&gt;. Some general lessons for a narrative game:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep event text as keyed templates with placeholders, not concatenated strings.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Intl.NumberFormat&lt;/code&gt; for currency and &lt;code&gt;Intl.PluralRules&lt;/code&gt; for "1 year / 2 years".&lt;/li&gt;
&lt;li&gt;CJK languages often need different line-height and truncation rules on share cards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Shareable output
&lt;/h3&gt;

&lt;p&gt;At the end of a life you can download a &lt;strong&gt;life card&lt;/strong&gt; image, plus a generated &lt;strong&gt;family tree&lt;/strong&gt;. Drawing to a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and exporting with &lt;code&gt;toBlob()&lt;/code&gt; is the usual browser-only way to make an image like this without a server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;Most of the "feel" comes from two choices: weighting the draw by real births, and letting real indicators drive the yearly odds. The rest is UX: pause, two reading speeds, an auto mode, and an &lt;a href="https://1in8billion.live/?edu=1" rel="noopener noreferrer"&gt;education mode&lt;/a&gt; for classrooms.&lt;/p&gt;

&lt;p&gt;You can try what I built at &lt;a href="https://1in8billion.live" rel="noopener noreferrer"&gt;1in8billion.live&lt;/a&gt;. It's free to play, with an optional US$2.99 one-time Keepsake card. I'd like to hear how you'd approach the hazard model.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>gamedev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
