<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>optional.is/required</title>
	<atom:link href="https://optional.is/required/feed/" rel="self" type="application/rss+xml" />
	<link>https://optional.is/required</link>
	<description>optional is required</description>
	<lastBuildDate>Thu, 09 Apr 2026 13:37:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>
<atom:link rel="hub" href="https://websubhub.com/hub"/>
<atom:link rel="self" href="https://optional.is/required/feed/"/>
	<item>
		<title>Hatena Burger Permutations</title>
		<link>https://optional.is/required/2026/04/09/hatena-burger-permutations/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Interfaces]]></category>
		<category><![CDATA[burgers]]></category>
		<category><![CDATA[combinations]]></category>
		<category><![CDATA[combinatorics]]></category>
		<category><![CDATA[hatena burger]]></category>
		<category><![CDATA[japan]]></category>
		<category><![CDATA[nintendo]]></category>
		<category><![CDATA[permutations]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=8874</guid>

					<description><![CDATA[Hatena Burger boasts over 270,000 burger combinations. Using some combinatorics, let's see if that's true.]]></description>
										<content:encoded><![CDATA[
<p>In Kyoto, Japan, in the Nintendo museum, there is a restaurant called <a href="https://museum.nintendo.com/en/cafe/index.html">Hatena Burger</a>. They claim to have over 270,000 different burgers you can order! Let&#8217;s investigate that claim to see how true it really is.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/hatena-burger.png" alt="Hatena Burger Logo"/></div>



<p>The way they can arrive at such a big number of possible burgers is to have a variety of different items you can combine in various ways. This quickly creates really big amounts of permutations.</p>



<p>Since you can build your own burger you get to choose 1 of 3 different bun types, 1 of 10 different main ingredients, 3 of 11 different toppings and 1 of 7 different types of sauces.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/hatena-burger-menu-jp.jpg" alt="A photo of the menu at Hatena Burger. Lots of icons representing possible choices to build your burger." /></div>



<p>To figure out all the possible combinations you simply multiple all these values together.</p>



<p><code>3 Bun types × 10 Main ingredients × 7 Sauces × (11 Toppings × 11 Toppings × 11 Toppings) = 279,510 possible combinations.</code></p>



<p>It does seem that there are over 270,000 possible burgers you can order, but that comes with several big asterisks! These are possible combinations with repetition. When you are selecting your 3 different  toppings order doesn&#8217;t matter, so Tomato, Lettuce and Cheese is considered a different burger than Lettuce, Cheese and Tomato, but most of us would agree it is the same thing. Also, you can select the same topping 3 times: a Cheese, Cheese, Cheese burger. What is the total possible combinations if we make sure the set of toppings is unique and order independent?</p>



<p>Todo so, we are not multiplying the total number of toppings (11) by the number you can choose (3). Instead we need to look into combinations without repetition using combinatorics. </p>



<p>First we select the number of possible combinations and then subtract the duplicates. We start with 11 different toppings, but once we select the first one, we only have 10 left, and after selecting the second, only 9 left. That&#8217;s 11 × 10 × 9 = 990 possibilities without repeating an ingredient. But that&#8217;s still order independent. We want to reduce that by the number of combinations of our 3 potential selections, which is 3! =  6. We can take 990 / 6 = 165. Then general equation is:</p>



<p>n!/(n-r)!  × (1/r!) where n is the number of times possible (11) and r is the number we can choose (3).</p>



<p>11! /(11-3)!  × (1/3!) = 165 possible combinations without repetition. That&#8217;s a lot lower than the 1,331 possible combinations of 11 × 11 × 11 Toppings or 990 of 11 × 10 × 9 Toppings without repetition.</p>



<p>If we plug that new value into our equation we get <code>3 buns × 10 mains × 7 sauces × ( 11 nCR 3 = 165 topping combinations) = 34,650 possible unique burgers</code>. That&#8217;s far less than the 279,510 possible burger combinations when we preserve the topping order.</p>



<h2 class="wp-block-heading">Interactive Examples</h2>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6a8.png" alt="🚨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> These examples require Javascript, so if you&#8217;re looking at this in a feed-reader or email client, it might not work. Check the original link to try these examples.</p>



<p>Channeling <a href="https://worrydream.com">Bret Victor</a>, let&#8217;s have a look at the possible combinations in a more interactive way. One of his approaches was to have inline text be editable, thus changing the flow of the paragraph. He advocated for green text inline being draggable to update the values. Let&#8217;s experiment with the following paragraph. <em>(Try dragging the text in green to the left or right to change the values)</em></p>



<p style="background-color: #dedede; padding: 20px; margin-bottom: 20px">At Hatena Burger, you can build your own burger by selecting from <span id="sliderBun" class="draggable-slider">3</span> different buns, <span id="sliderMain" class="draggable-slider">10</span> different main ingredients, <span id="sliderSauce" class="draggable-slider">7</span> different sauces and 3 of <span id="sliderTopping" class="draggable-slider">11</span> different Toppings. This gives <span id="draggable-result">279,510</span> different possible meals. </p>

<style>
.draggable-slider { color: white; background-color: green; border-radius: 10px; font-weight: bold; padding: 0 10px; cursor: grab; display: inline-block; width: 20px; user-select: none; text-align: center; }
#draggable-result { font-weight: bold; }
</style>

<script type="text/javascript">
var sliderBunValues = ['1','2','3','4'];
const sliderValues = {
 "sliderBun": [1, 2, 3, 4],
 "sliderMain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
 "sliderSauce": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 "sliderTopping": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
};

const spanBun  = document.getElementById('sliderBun');
const spanMain = document.getElementById('sliderMain');
const spanSauce = document.getElementById('sliderSauce');
const spanTopping = document.getElementById('sliderTopping');
const results  = document.getElementById('draggable-result');
let isDragging = false;

spanBun.addEventListener('mousedown', (e) => {
  isDragging = true;
  e.preventDefault(); // Prevent text selection
  document.body.style.userSelect = 'none'; // Prevent selection globally
});

spanMain.addEventListener('mousedown', (e) => {
  isDragging = true;
  e.preventDefault(); // Prevent text selection
  document.body.style.userSelect = 'none'; // Prevent selection globally
});

spanTopping.addEventListener('mousedown', (e) => {
  isDragging = true;
  e.preventDefault(); // Prevent text selection
  document.body.style.userSelect = 'none'; // Prevent selection globally
});

spanSauce.addEventListener('mousedown', (e) => {
  isDragging = true;
  e.preventDefault(); // Prevent text selection
  document.body.style.userSelect = 'none'; // Prevent selection globally
});


document.addEventListener('mouseup', () => {
  isDragging = false;
  document.body.style.userSelect = ''; // Restore selection

});

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;

  if (!document.getElementById(e.toElement.id)) { return; }


  // Get the X position relative to the span
  const rect = document.getElementById(e.toElement.id).getBoundingClientRect();
  let relativeX = e.clientX - rect.left;

  // Clamp the value between 0 and the span width
  relativeX = Math.max(0, Math.min(relativeX, rect.width));

  // Convert to a value (for example 0–100)
  var newValue = sliderValues[e.toElement.id]

  const value = Math.round((relativeX / rect.width) * (newValue.length - 1));
  // Update the span content
  document.getElementById(e.toElement.id).textContent = newValue[value];
  
  results.textContent = (parseInt(spanBun.textContent) * parseInt(spanMain.textContent) * parseInt(spanSauce.textContent) * parseInt(spanTopping.textContent) * parseInt(spanTopping.textContent) * parseInt(spanTopping.textContent)).toLocaleString();
});
</script>



<p>This is a great example of how changing the number of options by a small amount can make a big impact on the total permutations. The downside is that it overly simplify duplicate toppings and doesn&#8217;t allow for fine grained choices. Maybe not all the toppings or sauces are for me?</p>



<p>Let&#8217;s try again with a more complex menu. This allow the customer to limit the options not by a number, but by dietary preferences; Vegan, Vegetarian, Pescatarian, Dairy-free, Celiac, etc.</p>



<style>
.hb_box {
  display: inline-block;
  width: 80px;
  text-align: center;
  vertical-align: top;
  font-size: 80%;
}
.hb_box img { width: 80px; height: 80px; }
</style>

<h3>Buns</h3>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/bun-brown.png" />
  <label><input type="checkbox" class="hb_bun" name="hb_bun_1" id="hb_bun_1" value="1" checked="checked" /> Brown</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/bun-red.png"  />
  <label><input type="checkbox" class="hb_bun" name="hb_bun_2" id="hb_bun_2" value="2" checked="checked" /> Red</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/bun-black.png" />
  <label><input type="checkbox" class="hb_bun" name="hb_bun_3" id="hb_bun_3" value="3" checked="checked" /> Black</label>
</div>
<hr />

<h3>Main</h3>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-beef.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_1" id="hb_main_1" value="1" checked="checked" /> Beef Patty</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-double-beef.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_2" id="hb_main_2" value="2" checked="checked" /> Beef Patty Double</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-sukiyaki.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_3" id="hb_main_3" value="3" checked="checked" /> Sukiyaki Beef</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-double-sukiyaki.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_4" id="hb_main_4" value="4" checked="checked" /> Sukiyaki Beef Double</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-chicken.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_5" id="hb_main_5" value="5" checked="checked" /> Fried Chicken</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-double-chicken.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_6" id="hb_main_6" value="6" checked="checked" /> Fried Chicken Double</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-fish.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_7" id="hb_main_7" value="7" checked="checked" /> Grilled Miso Fish</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-double-fish.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_8" id="hb_main_8" value="8" checked="checked" /> Grilled Miso Fish Double</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-mushroom.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_9" id="hb_main_9" value="9" checked="checked" /> Big Mushroom</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/main-double-mushroom.png" />
  <label><input type="checkbox" class="hb_main" name="hb_main_10" id="hb_main_10" value="10" checked="checked" /> Big Mushroom Double</label>
</div>
<hr />
<h3>Toppings</h3>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-fried-egg.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_1" id="hb_top_1" value="1" checked="checked" /> Fried Egg</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-scrambled-egg.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_2" id="hb_top_2" value="2" checked="checked" /> Scrambled Egg</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-tofu.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_3" id="hb_top_3" value="3" checked="checked" /> Fried Tofu</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-kyoto-pepper.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_4" id="hb_top_4" value="4" checked="checked" /> Kyoto Green Pepper</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-onion.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_5" id="hb_top_5" value="5" checked="checked" /> Onion</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-cheese.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_6" id="hb_top_6" value="6" checked="checked" /> Cheddar Cheese</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-onion.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_7" id="hb_top_7" value="7" checked="checked" /> Kyoto Green Onion</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-lotus-root.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_8" id="hb_top_8" value="8" checked="checked" /> Stir-Fried Lotus Root</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-tomato.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_9" id="hb_top_9" value="9" checked="checked" /> Tomato</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-lettuce.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_10" id="hb_top_10" value="10" checked="checked" /> Lettuce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/topping-shibazuke-pickles.png" />
  <label><input type="checkbox" class="hb_top" name="hb_top_11" id="hb_top_11" value="11" checked="checked" /> Shibazuke Pickles</label>
</div>
<hr />
<h3>Sauces</h3>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-wasabi-garlic-soy.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_1" id="hb_sauce_1" value="1" checked="checked" /> Wasabi Garlic Soy Sauce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-sukiyaki.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_2" id="hb_sauce_2" value="2" checked="checked" /> Sukiyaki Sauce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-black-curry.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_3" id="hb_sauce_3" value="3" checked="checked" /> Black Curry Sauce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-shibazuke-pickles-tartar.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_4" id="hb_sauce_4" value="4" checked="checked" /> Shibazuke-Pickles Tartar Sauce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-ketchup.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_5" id="hb_sauce_5" value="5" checked="checked" /> Ketchup</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-citrus-pepper-dashi.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_6" id="hb_sauce_6" value="6" checked="checked" /> Citrus Pepper Dashi Sauce</label>
</div>
<div class="hb_box">
  <img decoding="async" src="https://optional.is/required/wp-content/uploads/2025/12/icons/sauce-veggie-aurora.png" />
  <label><input type="checkbox" class="hb_sauce" name="hb_sauce_7" id="hb_sauce_7" value="7" checked="checked" /> Veggie Aurora Sauce</label>
</div>
<hr />
<h3>Stats</h3>
<p>Based on your selection there are <strong id="hb_combinations">xxx</strong> possible burgers.</p>
<hr />
<script>
const bun_checkboxes = document.querySelectorAll('.hb_bun');
const main_checkboxes = document.querySelectorAll('.hb_main');
const sauce_checkboxes = document.querySelectorAll('.hb_sauce');
const top_checkboxes = document.querySelectorAll('.hb_top');

function onBunChange() {
  const atLeastOneChecked = Array.from(bun_checkboxes).some(cb => cb.checked);
  if (!atLeastOneChecked){
    document.getElementById('hb_bun_1').checked = 'checked';
  }
  do_hb_calculation()
}

bun_checkboxes.forEach(cb => {
  cb.addEventListener('change', onBunChange);
});

function onMainChange() {
  const atLeastOneChecked = Array.from(main_checkboxes).some(cb => cb.checked);
  if (!atLeastOneChecked){
    document.getElementById('hb_main_1').checked = 'checked';
  }
  do_hb_calculation()
}

main_checkboxes.forEach(cb => {
  cb.addEventListener('change', onMainChange);
});

function onSauceChange() {
  const atLeastOneChecked = Array.from(sauce_checkboxes).some(cb => cb.checked);
  if (!atLeastOneChecked){
    document.getElementById('hb_sauce_1').checked = 'checked';
  }
  do_hb_calculation()
}

sauce_checkboxes.forEach(cb => {
  cb.addEventListener('change', onSauceChange);
});

function onTopChange() {
  if (document.querySelectorAll('.hb_top:checked').length < 3){
    document.getElementById('hb_top_1').checked = 'checked';
    document.getElementById('hb_top_2').checked = 'checked';
    document.getElementById('hb_top_3').checked = 'checked';
  }
  do_hb_calculation()
}

top_checkboxes.forEach(cb => {
  cb.addEventListener('change', onTopChange);
});

function do_hb_calculation(){
  var combo_count = document.querySelectorAll('.hb_bun:checked').length * document.querySelectorAll('.hb_main:checked').length * document.querySelectorAll('.hb_sauce:checked').length * document.querySelectorAll('.hb_top:checked').length * (document.querySelectorAll('.hb_top:checked').length - 1) * (document.querySelectorAll('.hb_top:checked').length - 2)
  document.getElementById('hb_combinations').textContent = combo_count.toLocaleString()
}
do_hb_calculation()
</script>



<p>Finally, as you build your burger, you get a nice animated cartoon of your combination.</p>



<style>
.hb_stack { display: inline-block; width: 300px; text-align: center }
#hb_topping_1_1, #hb_topping_2_2, #hb_topping_3_3 {   animation: spin1 10s ease-in-out infinite alternate; }
#hb_topping_2_1, #hb_topping_3_2, #hb_topping_1_3 {   animation: spin2 11s ease-in-out infinite alternate; }
#hb_topping_3_1, #hb_topping_1_2, #hb_topping_2_3 {   animation: spin3 9s ease-in-out infinite alternate; }
@keyframes spin1 {
  0% { transform: rotate(-10deg); }
  100% { transform: rotate(10deg); }
}
@keyframes spin2 {
  0% { transform: rotate(8deg); }
  100% { transform: rotate(-12deg); }
}
@keyframes spin3 {
  0% { transform: rotate(-12deg); }
  100% { transform: rotate(7deg); }
}

</style>
<div style="text-align: center;">
<div class="hb_stack" style="text-align: center;">
<div><img decoding="async" id="hb_buntop_1" src=""  /></div>
<div style="position: relative; z-index: 100"><img decoding="async" id="hb_stack_sauce_1" src="" /></div>
<div style="position: relative; margin-top: -20px; z-index: 80"><img decoding="async" id="hb_topping_1_1" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 70"><img decoding="async" id="hb_topping_1_2" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 60"><img decoding="async" id="hb_topping_1_3" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 50"><img decoding="async" id="hb_stack_main_1" src="" /></div>
<div><img decoding="async" id="hb_bunbottom_1" src="" /></div>
</div>

<div class="hb_stack" style="text-align: center;">
<div><img decoding="async" id="hb_buntop_2" src=""  /></div>
<div style="position: relative; z-index: 100"><img decoding="async" id="hb_stack_sauce_2" src="" /></div>
<div style="position: relative; margin-top: -20px; z-index: 80"><img decoding="async" id="hb_topping_2_1" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 70"><img decoding="async" id="hb_topping_2_2" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 60"><img decoding="async" id="hb_topping_2_3" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 50"><img decoding="async" id="hb_stack_main_2" src="" /></div>
<div><img decoding="async" id="hb_bunbottom_2" src="" /></div>
</div>

<div class="hb_stack" style="text-align: center;">
<div><img decoding="async" id="hb_buntop_3" src=""  /></div>
<div style="position: relative; z-index: 100"><img decoding="async" id="hb_stack_sauce_3" src="" /></div>
<div style="position: relative; margin-top: -20px; z-index: 80"><img decoding="async" id="hb_topping_3_1" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 70"><img decoding="async" id="hb_topping_3_2" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 60"><img decoding="async" id="hb_topping_3_3" src="" /></div>
<div style="position: relative; margin-top: -10px; z-index: 50"><img decoding="async" id="hb_stack_main_3" src="" /></div>
<div><img decoding="async" id="hb_bunbottom_3" src="" /></div>
</div>

</div>

<p style="color: blue; cursor: pointer; text-decoration: underline; text-align: center;" onclick="random_hatena_burgers()">Reload Random Burgers</p>

<script>
function fisherYatesShuffle(array) {
    let currentIndex = array.length;
    while (currentIndex !== 0) {
        // Pick a remaining element
        let randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex--;

        // And swap it with the current element
        let temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }
    return array;
}

function random_hatena_burger(index){


const stack_buns = ['brown','red','black'];
const stack_sauces = ['black-curry','citrus-pepper-dashi','ketchup','shibazuke-pickles-tartar','sukiyaki','veggie-aurora','wasabi-garlic-soy'];
const stack_main = ['chicken','beef','fish','sukiyaki','mushroom','double-chicken','double-beef','double-fish','double-sukiyaki','double-mushroom'];

const stack_toppings = ['tofu','onion','tomato','shibazuke','lettuce','pepper','green-onion','lotus','cheese','egg','scrambled-egg'];


var bun_type = stack_buns[Math.floor(Math.random() * stack_buns.length)];
var bun_top = document.getElementById('hb_buntop_'+ index);
var bun_bottom = document.getElementById('hb_bunbottom_'+ index);
var sauce = document.getElementById('hb_stack_sauce_'+ index);
var sauce_type = stack_sauces[Math.floor(Math.random() * stack_sauces.length)];
var mains = document.getElementById('hb_stack_main_'+ index);
var mains_type = stack_main[Math.floor(Math.random() * stack_main.length)];

bun_top.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/bun-top-"+bun_type+".png"
bun_bottom.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/bun-bottom-"+bun_type+".png"
sauce.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/sauce-"+sauce_type+".png"
mains.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/main-"+mains_type+".png"

var topping1 = document.getElementById('hb_topping_'+ index+'_1');
var topping2 = document.getElementById('hb_topping_'+ index+'_2');
var topping3 = document.getElementById('hb_topping_'+ index+'_3');
var topping_types = fisherYatesShuffle(stack_toppings)

topping1.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/topping-"+ topping_types [0]+".png"
topping2.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/topping-"+ topping_types [1]+".png"
topping3.src = "https://optional.is/required/wp-content/uploads/2025/12/stack/topping-"+ topping_types [2]+".png"

}

function random_hatena_burgers(){
 random_hatena_burger(1);
 random_hatena_burger(2);
 random_hatena_burger(3);
}

random_hatena_burgers()
</script>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Does Hatena Burger have over 270,000 different burgers? Strictly speaking yes. Practically speaking, no. It&#8217;s much, much less when you remove duplicate toppings. Looking into the mathematics and combinatorics of the possibilities can be a fun and interesting way to see how adding or removing small amounts can have big impacts.</p>



<p>When we see what seems like outlandish claims &#8220;Over 270,000 possible burgers&#8221; it is within our abilities to double check and confirm or deny if it&#8217;s true.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Week #789 &#038; #790</title>
		<link>https://optional.is/required/2026/04/03/week-789-790/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Briefs]]></category>
		<category><![CDATA[Weeknotes]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[cities]]></category>
		<category><![CDATA[easter]]></category>
		<category><![CDATA[eCards]]></category>
		<category><![CDATA[mini-games]]></category>
		<category><![CDATA[webrtc]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9695</guid>

					<description><![CDATA[A double weeknote. The first half was stormy, the second half was Easter break.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Week #789</h2>



<p>We spent some time this week finishing-up a project for the concreters down in Australia. We will be taking over future work directly, so we&#8217;re preparing for all that.</p>



<p>We did a lot of brainstorming on some word puzzle mini-games. There is a kernel of something germinating. A few prototypes proved interesting, now we need to sit down with a wider audience and get feedback.</p>



<p>We continued to work on the WebRTC project by layering on a Pose Detection machine learning layer to highlight joins and features.</p>



<p>This week was also several meetings. Previously, we helped a small team put in a Gulleggið submission. Sadly, they were not selected in the top 10, so we all met to figure out the future of this idea. We also met-up with an old friend over zoom and chatted about higher-education, AI and Iceland. On Wednesday we met-up for morning coffee with another friend and chatted health care, AI, research and more. There might be some possibilities to work together in the future. <em>Always dig your well before you&#8217;re thirsty.</em></p>



<p>Thursday was an Orange Weather Alert day, so we mostly stayed home.</p>



<p>On Friday, we published our <a href="https://optional.is/required/2026/03/27/camelut/">Camelut article</a> detailing how we built a LUT bring your own filter camera. We also continue to update our camera apps with more small tweaks. Since it is a common library between them for the basic camera features, they all get the benefit of small updates and bug fixes.</p>



<h2 class="wp-block-heading">Week #790</h2>



<p>This is Easter week in Iceland with loads of public holidays and days off. Our work load was pretty minimal as we just had a few meetings and keep a few reoccurring tasks. Otherwise, we enjoyed the stormy Icelandic weather!</p>



<p>On Thursday, we had a few meetings about some new/old project ideas. That opened some big doors with quick deadlines, but we&#8217;ve been working towards this for a while.</p>



<p>Friday was the usual sync on a few other projects before the Holiday weekend.</p>



<h2 class="wp-block-heading">Bric-à-brac</h2>



<p>For a new prototype idea, we went back to some old, old UI designs around navigating through the metaphor of the city! These are the navigation headers from Kelloggs.com at the end of 01996 and beginning of 01997. That was a fun time on the web where big companies were still experimenting before  the standard mobile friendly navigation we have today.</p>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/kelloggs-Cereal-City-01996.gif" alt="Kelloggs.com December 01996" /></figure>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/Kelloggs-Cereal-city-01997.gif" alt="Kelloggs.com January 01997"/></figure>



<p>One thing you notice in Cereal City was the &#8220;Card Shop&#8221; for those who were not online in the late 90s, ePostcards were a big thing! Even Apple had a whole tab called &#8216;iCards&#8217; dedicated to sending HTML emails. This was probably a way to both collect email addresses, but also allow people to send HTML email before many mail clients supported it. Hotmail (HoTMaiL &#8211; see the reference) was started in 01995 and was one of the first Web-based email clients, before that AOL or Juno both were dedicated apps.</p>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/Screenshot-2026-03-24-at-15.31.37-1024x740.png" alt="Screenshot of archive.org of Apple's iCards page" /></figure>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Camelut</title>
		<link>https://optional.is/required/2026/03/27/camelut/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Briefs]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[camelut]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[LUT]]></category>
		<category><![CDATA[shaders]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=8804</guid>

					<description><![CDATA[Camelut is our third experimental iOS camera app - a bring your own filters camera. It takes industry standard LUT Cube files and applies them in real-time to your camera feed. ]]></description>
										<content:encoded><![CDATA[
<p style="text-align: center">
<a href="https://apps.apple.com/us/app/lut-photo/id6749096589?ls=1&#038;mt=8"><img decoding="async" src="https://is1-ssl.mzstatic.com/image/thumb/PurpleSource211/v4/a6/b9/a9/a6b9a91a-3080-417b-0c13-7156a6f8b203/Placeholder.mill/400x400bb-75.webp" alt="Camelut Logo"/></a>
</p>
<p style="text-align: center"><strong>Camelut is a bring your own filters camera.</strong></p>
<p style="text-align: center"><a href="https://apps.apple.com/us/app/lut-photo/id6749096589?ls=1&amp;mt=8">Download Camelut on the iOS App Store</a></p>



<p><a href="https://optional.is/apps/camelut/">Camelut</a> is our third experimental iOS camera app. It takes industry standard LUT Cube files which are used to color grade images and video and applies them in real-time to your camera feed as you take photos. </p>



<p>One of the benefits of LUT files is that you can find, download, install or create your own custom filters. This is something that other camera apps can&#8217;t do. Normally, you&#8217;re stuck with the filters they provide, but Camelut let&#8217;s you import your own. That&#8217;s the downside, you need to find, curate and manage your own filters. That&#8217;s not for everyone. With great flexibility comes great power.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/filter-samples.jpg" alt="Collage of images and iOS settings"/></div>



<p>To help you get started, we made three LUT files you can download and try. <strong>Download ZIP:&nbsp;<a href="optional-is-luts.zip">(optional.is) LUTs</a>&nbsp;(880 KB)</strong> </p>



<p>There are plenty of other LUTs out there for free and pay. You can even create your own in many popular image editing software tools. (Search for &#8220;Export Adjustments as LUT&#8221;)</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/camelut-sample.jpg" alt="" /></div>



<p>We implemented a bunch of non-intuitive features which mimic other photography apps, but are not exposed in the UI. For instance, when you take a photo with a filter, it appears in your photo library with the filter applied (as you&#8217;d expect). At some point we thought about also adding a button to save the original image, sans filter, as well. After digging around, we decided to add the source image and then as a second version of the filtered image to it. In the photos app, you can &#8220;revert to original&#8221; and you can get the source image. If you really want both, you can duplicate the image and remove the filter on one. This isn&#8217;t intuitive, but it&#8217;s also the way several other apps handle it, and we wanted to try to be a good photography app citizen and follow conventions.</p>



<p>Personally, we&#8217;ve been experimenting with 100+ different filters. The first time you take a picture they look horrible. You think, what&#8217;s the point of this filter? Then you&#8217;re outside in daylight and try the same filters again. This time they work really well, so it&#8217;s hard to delete a filter just in case! </p>



<p>We have several go-to filters, which is why we created 4 tag categories. We put similar Black and White LUTs together, created a Vintage style LUTs category, one for LUTs that work well Outdoors and another for our Favorites LUTs. This makes it easier to navigate around (by swiping) and find the best filter for the situation. You can create your own category names that make sense to your photography style.</p>



<p>This is now one of our go-to camera apps. Since it is our own itch to scratch, we&#8217;ll continue to explore, improve and support Camelut into the future.</p>



<p><a href="https://optional.is/apps/camelut/">Read more about Camelut</a> and basic features and functionality.</p>



<aside><p>There are a few ways you can create filters and effects on video streams. We previously wrote about the differences between <a href="https://optional.is/required/2025/08/27/lut-cubes-and-shaders/">LUT Cubes and Shaders</a>. For Camelut, we focused on LUT files since they are portable, but have their own limitations.</p></aside>



<p><a href="https://apps.apple.com/us/app/lut-photo/id6749096589?ls=1&amp;mt=8">Download Camelut on the iOS App Store</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Week #787 &#038; #788</title>
		<link>https://optional.is/required/2026/03/20/week-787-788/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 20 Mar 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Briefs]]></category>
		<category><![CDATA[Weeknotes]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[GDC]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[surveys]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9654</guid>

					<description><![CDATA[Another double weeknote. We're still deep in app and surveys, but there is light at the end of the tunnel.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Week #787</h2>



<p>This week we posted about <a href="https://optional.is/required/2026/03/12/sxsw-02006/">our trip to SXSW Interactive in 02006</a> (twenty years ago!). We mentioned meeting some of the folks behind 43things. This week we actually found our old list from their website on archive.org.</p>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/archive-org-43things-briansuda.png" alt="Briansuda's 43things profile on archive.org" /><figcaption><a href="https://web.archive.org/web/20060423090553/http://www.43things.com/person/briansuda">Briansuda&#8217;s 43things profile on archive.org</a></figcaption></figure>



<p>Of the seven things we had on our list, we did move to another country, we debatably learned a new language and we certainly wrote a book. There&#8217;s still time to be interviewed on TV as a guest.</p>



<p>This week was the GDC conference in San Francisco. We did not attend this year, but some of our partners were there having lots of meetings. In the next few weeks we&#8217;ll see how that impacts our current and potential projects.</p>



<p>Since we&#8217;ve been deep in Xcode and Swift programming, we continued to updated a few apps to SwiftUI. In the process also fixing some crash errors people have been experiencing. Xcode does give you crash reports with some stack trace of what happened. We fixed a bunch of deep errors on the <a href="https://itunes.apple.com/us/app/shipping-forecast-mindfulness/id1226922380?ls=1&amp;mt=8">Mindfulness Shipping Forecast app</a> while we updated that to a modern code-base. In the process we improved the voice, added some tips, dark mode and fixed a bunch of bugs.</p>



<p>The other app that still had not been updated was <a href="https://apps.apple.com/us/app/newsletters/id1455564424?ls=1&amp;mt=8">Newsletters</a>. Much like <a href="https://triagemail.com">Triagemail</a> was, Newsletters used Mailcore to handle the IMAP messages. This week, we switched over to SwiftMail to both modernize the app and make it easier to maintain and port. The progress has been going well and we continue to find and fix bugs in the differences between the two libraries.</p>



<p>Throughout the week, we had several small tasks regarding all our surveys. For the parent surveys, we randomly select one of the two guardians to take the survey. Half-way through the month, we switch guardians. This gives the first a chance to answer and if after several reminders they still do not want to participate, we swap for the other guardian and let them have a chance to contribute. We did the swap on Monday and started the reminder schedule of email, sms, email. Next week we&#8217;ll email, robocall, email again. Depending on the response rate for customers, we might try a targeted SMS or email in English. For other on-going surveys we also sent out emails and robocalled this week. All of these surveys will end before the Easter break, so we&#8217;re trying to leave ourselves the last week of March for adjustments to reminders before people checkout for the holidays.</p>



<h2 class="wp-block-heading">Week #788</h2>



<p>On Monday, we sent out more survey reminder emails. We use Heroku as the hosting platform and we have background tasks to send all the messages. Thanks go GMail&#8217;s aggressive bulk/spam detection we need to put a second delay between sendings. It&#8217;s only been recently that our heroku background task has been producing enough memory leak errors that the process gets shutdown. We haven&#8217;t changed anything for years, so it is most likely heroku getting stricter. These last few weeks we&#8217;ve been trying a few different changes and memory profiling to mitigate the leaks.</p>



<p>We continue to tweak a few of the iOS camera apps. The Newsletter app is in good shape, we&#8217;re continuing the test and fix anything before we release it.</p>



<p>Our Australian concreters also sent over a list of changes. It&#8217;s great that they are using the system and have feedback, but their emails can be short and confusing. We&#8217;ll do what we can and then get clarification on a few other points. Luckily, this is all billable time. A few weeks ago, we thought the project was done, so we sent off the last invoice and they renegotiated the hourly rate due to general inflation. These updates are now under the new rate. On Wednesday, we got a message from our contact that he&#8217;s interested in extricating himself as the middleman. It means we take-over the project directly at a higher hourly rate. We&#8217;ll most likely do it, but the timezone difference and the small hours could potentially be a hassle.</p>



<h2 class="wp-block-heading">Bric-à-brac</h2>



<p>We found this great little puzzle game: <a href="https://murdoku.com/?lang=en">Murdoku</a> &#8211; Sudoku meets murder mystery</p>



<figure class="banner"><a href="https://murdoku.com/?lang=en"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/03/murdoku_grid_website.png" alt="Murdoku example map" /></a></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SXSW 02006</title>
		<link>https://optional.is/required/2026/03/12/sxsw-02006/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Thu, 12 Mar 2026 12:21:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[austin]]></category>
		<category><![CDATA[friends]]></category>
		<category><![CDATA[sxsw]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[web 2.0]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9263</guid>

					<description><![CDATA[Twenty years ago today, (March 10th-15th) we gathered in Austin, Texas for SXSW interactive festival.]]></description>
										<content:encoded><![CDATA[
<p>Twenty years ago, (March 10th-15th 02006) we gathered in Austin, Texas for the SXSW interactive festival. As we think back to that event, it is one of those pivotal &#8216;sliding doors&#8217; moments. It felt like a big wave was swelling and we did well to get right in front of all the action.</p>



<p>To put things into a bit of context, this was 02006, the iPhone was still 10 months way from launch. The world was Blackberries, Nokias and Palm Pilots. We split a hotel room with 2 other people. As reimbursement, we wrote a physical cheque to pay for the hotel stay.</p>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/01/sxsw-2006-website.jpg" alt="Screenshot of sxsw.com from 2006"/><figcaption>Screenshot from <a href="https://web.archive.org/web/20060221113710/http://2006.sxsw.com">Archive.org of SXSW.com from 02006</a>.</figcaption></figure>



<p>This is what most of the web used to look like before mobile devices and stacked layouts! We had columns and tiny text. Call out buttons, banner images, navigation tabs and more.</p>



<p><a href="https://en.wikipedia.org/wiki/Web_2.0">Web 2.0</a> and <a href="https://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a> were buzz-words. There was a certain expectation of how we&#8217;d use a website. This is pre-twitter, Facebook was only 2 years old and just started to allow anyone besides .edu email address to register.</p>



<p>Tagging and <a href="https://en.wikipedia.org/wiki/Folksonomy">Folksonomies</a> were also something new and exciting. The ability to create ontologies from the bottom-up rather than top-down was creating a stir. There were several panels on the topic. At the time the photo sharing site <a href="https://www.flickr.com/search/?text=sxsw06">Flickr</a> had tags and started to create super-groups based on tag clusters. We vividly remember sitting in one session where they explained how they did this with k-means clustering, and then in another some panelist swore it was so good it must be human curated. If that were today, it would be the opposite, the default assumption would be LLMs and AI made the tags and when it&#8217;s actually human curated we&#8217;re surprised.</p>



<p>Oh the crazy parties. It seemed like every small venue turned into some interactive party or off-venue party. We met so many interesting people. We remember talked with someone from <a href="https://robotcoop.com">Robo Co-op</a> about their sites <a href="https://en.wikipedia.org/wiki/43_Things">43 Things</a>, 43 Places, 43 People, etc. We were avid users of the sites so to meet someone who created it was amazing. Then at another event, a WordPress meetup, we meet <a href="https://ma.tt/2006/03/sxsw/">Matt Mullenweg</a> the creator. WordPress was less than three years old and they were still evangelizing the software. We also remember standing in a parking lot outside of a venue and met <a href="https://en.wikipedia.org/wiki/Joshua_Schachter">Joshua Schachter</a> who had created <a href="https://del.icio.us">Del.icio.us</a> which we were an early adopter of. He was chatting to someone else, and we just listened, border-line weird.</p>



<p>The hot new geolocation <a href="https://en.wikipedia.org/wiki/Dodgeball_(service)">Dodgeball</a> was all the rage. As people you followed checked-into venues you&#8217;d get an SMS. One minute we were sitting having a drink, then everyone&#8217;s phones started to buzz and they all moved like a string of ants to the next party. While technology connects us and does great things, it was our first reminder that sometimes what&#8217;s right in front of you is just fine. Always searching for where the grass is greener isn&#8217;t necessarily the best way to live life. We experienced that with people too. SXSW brings together ALOT of people who you&#8217;d never normally see or get access too. There were times someone was engaged in a conversation in our group, saw someone &#8220;more famous&#8221; and stopped mid-sentence and walked away. It was bewildering behavior, but another lesson learnt.</p>



<p>We were there because we&#8217;d volunteered working on <a href="https://microformats.org">Microformats</a>. This was a way to embed a bit of extra hints at what your HTML content was representing using already established means. Human-readable text then could be extracted by machines and converted into other formats, like calendar events and contacts. It was certainly picking-up speed compared to the more complicated and machine focused RDF.</p>



<figure class="banner"><img fetchpriority="high" decoding="async" width="1000" height="663" src="https://optional.is/required/wp-content/uploads/2026/03/sxsw06-microformats.jpg" alt="Microformats crew sitting around at SxSW 2006" class="wp-image-9643" srcset="https://optional.is/required/wp-content/uploads/2026/03/sxsw06-microformats.jpg 1000w, https://optional.is/required/wp-content/uploads/2026/03/sxsw06-microformats-300x199.jpg 300w, https://optional.is/required/wp-content/uploads/2026/03/sxsw06-microformats-768x509.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" />
<figcaption><a href="https://www.flickr.com/photos/adactio/113270200/">The Microformats Mafia</a> Photo by Jeremy Keith, licensed as CC BY 2.0</figcaption>
</figure>



<p>We made a lot of new friends on that trip. Many of which we are still in contact with today. That lead to working professionally with and for many of them. Browsing through the nearly <a href="https://www.flickr.com/search/?text=sxsw06">10,000 photos on Flickr tagged sxsw06</a>, there are a lot of memories, people who are no longer with us, some things people probably wished weren&#8217;t online, products and companies that have come and gone, and more. That time at SXSW was unique. The event continues today, but it isn&#8217;t the same. </p>



<p>In this post-pandemic, war-torn 02020s, conferences and events like SxSW06 are hard. In the last 20 years, everyone&#8217;s realized the importance of the Web and internet and there have plenty of grifts, NFTs, Crypto, ICOs, Web 3.0, and AI are just some of the big ones. To gather so many like-minded, energetic people in once place and not have it ruined by corporate greed felt unique.</p>



<p>We&#8217;re happy we got to attend and in some small way would like to think we&#8217;ve left the Web a better place because of it.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Week #785 &#038; #786</title>
		<link>https://optional.is/required/2026/03/06/week-785-786/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 06 Mar 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Weeknotes]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[survey]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9611</guid>

					<description><![CDATA[A double weeknote mostly focused on Surveys and in-between we made some iOS app updates.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Week #785</h2>



<p>This week we spent a bunch of time between tasks working on some of our iOS apps. For all the Camera App, we did a big refactor to share more code between them. That will make finding and fixing bugs and adding features faster. We also add GeoTagging of the photos and better metadata when saving.</p>



<p>We also refactoring <a href="https://triagemail.com">Triagemail</a> to handle multiple IMAP accounts and <a href="https://dashbones.com">Dashbones</a> to bring it up from Swift to SwiftUI to make it easier to maintain and update.</p>



<p>As a test, we also scratched our own itch and created an offline music player. We have several mp3s and other audio clips that are not on streaming services. We still wanted a way to play some of this music since it&#8217;s mostly been lost these last few years to streaming.</p>



<p>With some spare time, we also make an ugly prototype app for a game idea we&#8217;ve had kicking around for a long, long time. Much like the original Lemonade game for the Apple IIc, the goal is to both plan, balance and iterate on a small business. The prototype is great because it&#8217;s horrible! Somethings are too fast, somethings too small, others don&#8217;t make sense and the economy doesn&#8217;t balance, but now we can fix it all and build a plan rather than keep things idea locked-up.</p>



<p>On Thursday we published <a href="https://optional.is/required/2026/02/26/backups-3-0-remote/">Backups 3.0</a>, a look at the state of our ever evolving backup regime.</p>



<p>Thursday was the Gulleggið presentations. We went to have a look at the top 10 entries for new start-up ideas. It was fun and interesting. Afterwards we chatted with some teams about similar things we&#8217;ve worked on and if we could help in anyway. Slowly, we&#8217;re getting back into the local community and digging our well before we&#8217;re thirsty.</p>



<p>With February ending and March starting we&#8217;re deep in survey season. We wrapped-up one, started another and will start a 3rd next week. The core application is in great shape, we&#8217;re mostly dealing with importing of lists, various question issues, etc.</p>



<p>March also means that we need to do all the payroll, bills, VAT statements and annual taxes. We&#8217;re pretty well on top of all these tasks, but they still need to get done soon.</p>



<h2 class="wp-block-heading">Week #786</h2>



<p>This week we started yet even more surveys and wrapped-up another. Each is run on it&#8217;s own server, so we&#8217;re not concerned about the backend technology part, it is more the juggling of who gets contacted when and how. Before a survey starts we usually create some sort of &#8220;pester schedule&#8221; which outlines all the actions we take and on what days. For instance, Monday we send out first email, then Wednesday SMS follow-ups, etc. That helps us keep track of everything across various surveys in different states of progress.</p>



<p>This week we sent a lot of emails, SMSs and Robocalls!</p>



<p>Each year we release a big list of headlines we collected as part of the (Today I learnt) <a href="https://optional.is/required/tag/til/">TIL project</a>. We continue to work on it little by little. So far, we&#8217;ve put all the headlines into a database and tagged (most) all the entries. There is some next level work we&#8217;d like to get around to smoothing out and we&#8217;re almost there!</p>



<p>We got back in to Xcode this week and cleaned-up more apps. We submitted <a href="https://dashbones.com">Dashbones</a> and <a href="https://triagemail.com">Triagemail</a> for App Review and they are now live on the App Store. Our camera app refactoring is going to take a little bit longer since we got sucked into more prototyping ideas.</p>



<p>On Friday, we had a few meetings to sync about projects. With all these other deadlines, prototypes and distractions, our focus has fallen short on a few others. Luckily, things are getting back to a normal level of chaos so we can regroup on a few older projects that need some attention again.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Backups 3.0 Remote</title>
		<link>https://optional.is/required/2026/02/26/backups-3-0-remote/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[DAS]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[icloud]]></category>
		<category><![CDATA[LOCKSS]]></category>
		<category><![CDATA[NAS]]></category>
		<category><![CDATA[VPN]]></category>
		<category><![CDATA[VPS]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9209</guid>

					<description><![CDATA[The third in the series where we continue to improve our backups, partly out of necessity.]]></description>
										<content:encoded><![CDATA[
<p>RAID is not a backup!</p>



<p>In part 3: We continue to extend our backup regime by adding a remote NAS. (<a href="https://optional.is/required/2024/03/19/backup-2-0-das-edition/">part 2 DAS Edition</a>, <a href="https://optional.is/required/2022/05/31/backups/">part 1 Backups</a>)</p>



<p>We&#8217;re lucky enough to have some family a few timezones away that were willing to stick a small NAS box on a shelf for us. At the time we went with a very simple, entry level Synology 2-bay NAS solution. We didn&#8217;t need RAID redundancy or any media server encoding. This was our off-site, cold-storage, 3rd copy backup. Hopefully, we won&#8217;t need it.</p>



<p>This is our &#8216;3&#8217; and &#8216;1&#8217; in the 3-2-1 backup rule. (3 copies, 2 mediums, 1 offsite).</p>



<p>To make this as easy as possible, we took advantage of our Unifi routers. Along with the NAS we also bought a Unifi Express. We created a private VPN between our office network and the remote network. Doing so makes all the devices on that network seem as if they are on our local network. We can SMB:// into a &#8220;local&#8221; IP address to our remote NAS.</p>



<p>Now that we have an 8TB hard drive in a NAS a few timezones away that seems like it is local, we can create a cron job which <code>rsyncs</code> from our local DAS to the remote NAS.</p>



<p>The current hardware setup is a 4-bay DAS connected to an older Mac mini. The first two bays contain 4TB hard drives for work and personal data. The 3rd bay is an 8TB hard drive which contains a copy of the first two 4TB drives. Each night the Mac mini runs a cron job to <code>rsync</code> the data to the 3rd drive. We do this rather than RAID for two reasons. We can have multiple drive sizes and if it were in RAID and we accidentally delete or corrupt a file, it is instantly also deleted or corrupted on the mirrored drive too. From time-to-time, having a daily delay has proven useful. With this setup we have &#8216;2&#8217; copies of the data. The 4th hard drive is another 4TB drive we use as a Time Machine backup for our laptops. That makes &#8216;2&#8217; copies there too (the laptop and the Time Machine backup)</p>



<p>We also have an external 4TB hard drive we use as an &#8220;air gapped&#8221; Time Machine. We plug that in about once a month to our laptops to also create a backup (just in case!).</p>



<p>Nightly, we also <code>rsync</code> from the 8TB drive on the DAS to the 8TB drive on the remote NAS. At the moment, it is not using the full disk space, so we also weekly <code>rsync</code> the 4TB Time Machine drive to the remote NAS. With time, we&#8217;ll fill-up the hard drive, but the remote NAS has 2-bays and one is still empty.</p>



<p>The way the Time Machine backups are structured means that a small incremental update causes a lot of files to change. If a large file changes just a tiny bit, we still need to rsync the whole file over to the remote NAS. We decided that a weekly remote Time Machine backup would be enough. We have two local copies (plus the laptop itself) if needed.</p>



<h2 class="wp-block-heading">Webhosting</h2>



<p>Most all our websites and web apps reside in one of two places: Heroku or Opalstack. Heroku is our goto service for web apps for customer projects. Everything you deploy there is via git version control, so we have a copy on heroku, locally and in a git repository (usually bitbucket or GitHub). 3-2-1 is covered. Any databases are backed-up nightly in the cloud, but technically that&#8217;s just &#8216;2&#8217; locations and &#8216;1&#8217; offsite. (A 3rd backup would be best)</p>



<p>Opalstack is our VPS (Virtual Private Server). We host a lot of static website, WordPress, personal projects and file storage there. We&#8217;ve had bad experiences with previous VPSes like Joyent, Textdrive, and WebFaction, from having no backups to being acquired. We needed to make sure that anything created there we have a local copy of as well.<br /><br />To solve this, we have a cron task on the VPS that dumps all the databases to flat files. Then we added to our local rsync script to grab all the files: database dumps and html directories from the VPS and put them onto the DAS. Once they are there, they get absorbed into the 3-2-1 system.</p>



<h2 class="wp-block-heading">Backups still not covered</h2>



<p>We have done a great job getting to the 3-2-1 for all our local files. Our laptops and file server are all automatically being backed up. So what&#8217;s left?</p>



<p>Our devices (iPhones and iPads) are only backed up to iCloud. That&#8217;s mostly fine, except that photos are pretty important and (we feel) too fragile on iCloud. The way iCloud works, is to save space on your device sometimes you only get image thumbnails, and then if you delete a picture on your laptop to save space, it might purge it everywhere, including your phone. To mitigate this, we use the &#8220;Image Capture&#8221; app (or Photos.app) on the laptop to copy all recent images to the hard drive. Then it is part of our local backup regime.</p>



<p>The other major sources of data that are not currently in any sort of regular backup routine are our cloud-base services. Files in Google Drive, iCloud Drive, Trello, Asana, email, etc. are assumed to be &#8220;backed up&#8221; by the service provider, but we&#8217;ve had instances where that&#8217;s not true. Our email address could get flagged (for no reason) and our account suspended locking us out of our data. Our next big task is to list all the places that have data only in other systems (mastodon for instance) and get an automated cron job to save that date to our DAS and into our 3-2-1 backup regime.</p>



<p>Every iteration where improve the backup plan gets both more difficult and the data gets smaller. Looking back, we&#8217;ve gone from nothing (or Dropbox), to a pile of external hard drives and Time Machine, to a DAS with a schedule and system in place, to a remove NAS and syncing our website data. Each step has improved our redundancy and safe guarded the data we feel is important. We&#8217;ll never be &#8220;DONE&#8221;, but with every small step, we get closer.</p>



<h2 class="wp-block-heading">Addendum: We got lucky!</h2>



<p>Recently, we had one small backup disaster that was outside out 3-2-1 system. We recovered most, if not all, of the data by shear chance.</p>



<p>There were several old email accounts setup from previous projects on the iPhone that were just causing problems. The accounts closed several years ago and the login didn’t work. So we deleted them. It&#8217;s good practice to clean-up and not leave any un-used accounts lingering for longer than needed.</p>



<p>Then a day later we realized that half the contacts were gone. Somehow, that old account was the default for all new contacts created. Normally this wouldn’t be a big issue since the contacts would be synced with the server, but since that connection was broken awhile ago those contacts ONLY existing on the phone. Now they&#8217;re gone. We looked in Time Machine backups for the computer&#8217;s contacts database, but they were never synced there. We looked on iCloud but they were not there either, since they were never synced there. The laptop didn’t have a back-up of the iPhone since that’s now managed by iCloud. iCloud DOES have a backup of the phone, but only the most recent, and that’s already been overwritten and lost all the contacts.</p>



<p>It was only by luck that a few months ago, we upgraded the old iPhone 12 to a less old iPhone 13 and the iPhone 12’s backup was still in iCloud. We did the dance of backing up the iPhone 13, restoring the 12’s backup, getting all the lost contacts moved to iCloud, and restoring the 13’s backup again. It took a few hours, but we restored the contacts. This experience shed a light on a few areas of improvement in our backup regime. The first thing we did was check to make sure any new contact was being put into iCloud by default. We also took a manual vCard backup of the contacts and added that into the 3-2-1 system.</p>



<p><strong>Remember L-O-C-K-S-S, Lots Of Copies, Keep, Stuff, Safe.</strong></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Week #783 &#038; #784</title>
		<link>https://optional.is/required/2026/02/20/week-783-784/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Briefs]]></category>
		<category><![CDATA[Weeknotes]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[spellstruct]]></category>
		<category><![CDATA[surveys]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9398</guid>

					<description><![CDATA[A double weeknote heading into the Easter season. We worked on half-a-dozen different projects - that kept us busy.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Week #783</h2>



<p>This week we took delivery of two hardware security cameras. These are for a project where we need to create an iPhone app that scans the QR code on the bottom of the device, connects to that device&#8217;s WiFi network and issues commands to both set the RTMP stream URL, but also transfer WiFi settings so the camera can join the local network. We took care of our part, but now it&#8217;s back to someone else to get the server component all flushed out.</p>



<p>For our school surveys, we sent out around 10,000 SMS reminders, the a few days later we did our Robocalls. <a href="https://optional.is/required/2021/05/03/robocalling/">We&#8217;ve written about our use of Robocalling</a> and how effective it can be to get our response rate up. The surveys continue until the end of the month, when we shift gears to reporting and starting another two surveys.</p>



<p>On Monday, we met with a small team that&#8217;s beta testing our time tracking software. We&#8217;ve been working on web-based time tracking and project management for a while. Now we&#8217;ve put all that knowledge together into something we think is unique. After this beta test, we&#8217;ll know a lot more about where to take things next.</p>



<p>Our Australian Concreters started a spin-off company selling Screw Piles. Over the last few months, we&#8217;ve forked the web app and changed the logo and colors in a few places and updated some fields to either be more generic or wrap them in conditionals depending on the company. What we thought was two companies, is now sort-of three. There was some confusion in the naming, but we fixed a that and a few bugs this week.</p>



<p>We managed to get a few meetings in with friends and old colleagues. We have a few projects stirring that we&#8217;re trying to get off the ground. Getting everyone in on a meeting helped start that ball rolling.</p>



<h2 class="wp-block-heading">Week #784</h2>



<p>This week we started to plan a few more social meet-ups. We&#8217;ve grab morning coffee with some folks and lunch with a few more. Lots of emails have been sent and we&#8217;re trying to reconnect more with the local tech scene. This is all in the name of &#8220;Dig your well before you&#8217;re thirsty&#8221;. We&#8217;re in no dire need of work or projects, but given the shift in geo-politics in our industry with the rise of AI and globally with the US, we wanted to make sure people know about us closer to home. We&#8217;ll continue to meet-up with folks. We&#8217;ve been learning a bunch, validating some of our ideas and having a great time catching-up with old colleagues we haven&#8217;t seen in years.</p>



<p>We have a pretty good back-up regime in place, but this week one small backup disaster occurred that we managed to avert (no thanks to our setup)! One on iPhone we had several old email accounts setup from previous projects. They&#8217;ve been long over for years, the login didn&#8217;t even work, so we deleted it. Then a day later we realized that half our contacts were gone. Somehow, that old account was the default for all new contacts created. Normally this wouldn&#8217;t be a big issue since they would be sync with the server, but since that connection was broken those contacts ONLY existing on the phone and now they were gone. We looked in Time Machine backups for the computer, but they were never synced there. We looked on iCloud but they were not there either, since they were never synced there. The laptop didn&#8217;t have a back-up of the iPhone since that&#8217;s now managed by iCloud. iCloud DOES have a backup, but only the most recent, and that&#8217;s already lost all the contacts.</p>



<p>It was only by luck that a few months ago, we upgraded the only iPhone 12 to a 13 and the 12&#8217;s backup was still in iCloud. We did the dance of backing up the 13, restoring the 12&#8217;s backup, getting the lost contacts saved to iCloud, and restoring the 13&#8217;s backup again. It took a few hours and we probably only lost a few contacts, but it did shed a light on a few areas of improvement in our backup regime.</p>



<p>Between all these tasks and meetings was more survey work. We send out emails and robocalls to our current surveys and survey prep another one to start in March and yet another to start in a week or so. That requires minor changes to the questions, but more importantly to how we are converting the list of potential participants to a stratified random sample of actual participants.</p>



<h2 class="wp-block-heading">Bric-à-brac</h2>



<figure class="wp-block-image size-large"><a href="https://apps.apple.com/us/app/disney-spellstruck/id1616724721"><img decoding="async" width="1024" height="576" src="https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x-1024x576.jpg" alt="" class="wp-image-9554" srcset="https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x-1024x576.jpg 1024w, https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x-300x169.jpg 300w, https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x-768x432.jpg 768w, https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x-1536x864.jpg 1536w, https://optional.is/required/wp-content/uploads/2026/01/Apple-Arcade-Disney-SpellStruck_big.jpg.large_2x.jpg 1960w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>On Thursday, <a href="https://apps.apple.com/us/app/disney-spellstruck/id1616724721">Star Wars SpellStruck</a> finally was released. We&#8217;ve been quietly working on this update for a while now and we&#8217;re happy it&#8217;s live.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Wyld&#8217;s Great (VR) Globe</title>
		<link>https://optional.is/required/2026/02/12/wylds-great-vr-globe/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Thu, 12 Feb 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Briefs]]></category>
		<category><![CDATA[globe]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[projections]]></category>
		<category><![CDATA[VR]]></category>
		<category><![CDATA[worldmapper]]></category>
		<category><![CDATA[Wyld]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=8656</guid>

					<description><![CDATA[In 01851, it was possible to step inside a globe to see an inverted projection of the Earth's surface. 170 years later, we've recreated the experience in VR using new cartograms.]]></description>
										<content:encoded><![CDATA[
<p>Back in 01851, the notable mapmaker James Wyld created a giant (60ft ~18.5m) globe in Leicester Square, London, England. It was there for nearly 11 years and built to capitalize on the Great Exhibition tourism. His globe was unique in that the map was rendered on the inside of the sphere rather than the outside. The projection on the globe matches that of the Earth so everything is scaled and positioned correctly.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/01/Greatglobe_sectional.png" alt="Woodblock carving of the cross-section of the building holding a sphere representing the globe" /></div>



<p>You&#8217;d enter and ascend stairs to various viewing platforms. From there you can see the globe from various angles. Being on a sphere reduces the distortion you&#8217;d get from various other maps that over-emphasizing the poles compared to the equator.</p>



<p>Over time, interest in <a href="https://en.wikipedia.org/wiki/Wyld%27s_Great_Globe">Wyld&#8217;s Great Globe</a> decreased until closure. Today, the Mapparium in Boston is the only globe you can enter and view from the inside. It was built in 01935 and is only half the diameter of Wyld&#8217;s.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/02/The-Mapparium-Boston-1024x681-1.jpg" alt="Mapparium in Boston. View inside the globe while walking over a bridge which bisects the sphere." /></div>



<p>These are unique experiences which change the way you look at and understand our Earth. We wanted to explore if it was possible to recreate this experience digitally using Virtual Reality.</p>



<p>For other projects we&#8217;ve wrapped 180 and 360 images onto the inside of a sphere, so it should be simple todo the same thing with a 2D map using the right projections.</p>



<p>Working with the <a href="https://worldmapper.org">Worldmapper</a> team, we took several of their equalrectangular projection maps and put them into a sphere in Virtual Reality. With a VR headset, you can look around 360 degrees, and simulate being inside a globe with the map rendered on the inside surface.</p>



<figure class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/01/davinci-resolve.png" alt="Screenshot with two panes, the first is inside of a sphere with a world map projected onto it. The second pane is the Equalrectangular version of the map" />
<figcaption>Using DaVinci Resolve, we wrapped the 2D cartogram to the inside of a sphere.</figcaption>
</figure>



<p>The Worldmapper team have worked extensively with various datasets to warp and bulge countries, regions and continents based on the data. Rather than the country being represented on the globe based on their square meterage, it is possible to visualize it based on population, tree coverage, mobile phone usage, and more.</p>



<p>Seeing all the different data sets as flat 2D images is interesting, but seeing them rendered all around you in a sphere is much more impactful!</p>



<p>We packaged everything-up in an app for the Apple Vision Pro. There you can select from a list of categories to view the cartograms as if you were standing inside the globe. </p>



<figure class="banner"><video controls src="https://optional.is/required/wp-content/uploads/2026/02/worldmapper-avp-480.mov" style="width:100%"></video>
<figcaption>NASA Black Marble in 360</figcaption>
</figure>



<p>Technically, if you were on the inside of the Earth looking at the underside of the continents, you should see them reversed to what you&#8217;d expect on a globe. We tested this, but the reaction wasn&#8217;t positive; people need the shapes and outlines they are used too to orient  themselves. So we applied the maps to the inside the sphere &#8216;mirrored&#8217; so they look &#8216;correct&#8217;.</p>



<p>As part of an outreach exhibition, we created a short looping video of several maps crossfading between each other. There were 10 or so static maps by Worldmapper and NASA and one animated &#8216;<a href="https://worldmapper.org/natures-heartbeat/">heartbeat</a>&#8216; map. Since they were all in equalrectangular projection, we could use some VR video playback software to play this 2D video as if it were 360 degrees.</p>



<p>The looping video isn&#8217;t as nice as a dedicated app where you can select the topic and explore as long as you&#8217;d like, but it works in all places that you can view 360 images. This makes demoing on other VR devices, and even smart phones with accelerometers, quick and easy; you pick it up, look for a bit and put it down when you&#8217;re done.</p>



<p>The reception was great, we learnt a lot and will continue to improve the app designs and cartograms. These tools help the Worldmapper team expand their offerings: from 2D printed postcards, to touch screen interactive maps, to a 360 VR movie, and 360 VR interactive cartograms. As a tool for outreach these VR experiences are proving popular. They give a certain <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4af.png" alt="💯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> factor that&#8217;s hard to recreate elsewhere.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/02/1770768542494.jpeg" alt="A person with an Apple Vision Pro headset on" /></div>



<p>How many chances do you get to stand at the center of Earth and explore the continents?</p>
]]></content:encoded>
					
		
		<enclosure url="https://optional.is/required/wp-content/uploads/2026/02/worldmapper-avp-480.mov" length="8800907" type="video/quicktime" />

			</item>
		<item>
		<title>Week #781 &#038; #782</title>
		<link>https://optional.is/required/2026/02/06/week-781-782/</link>
		
		<dc:creator><![CDATA[optional Bot]]></dc:creator>
		<pubDate>Fri, 06 Feb 2026 13:31:00 +0000</pubDate>
				<category><![CDATA[Briefs]]></category>
		<category><![CDATA[Weeknotes]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AVP]]></category>
		<category><![CDATA[gulleggið]]></category>
		<category><![CDATA[llm]]></category>
		<category><![CDATA[SMS]]></category>
		<category><![CDATA[starling]]></category>
		<category><![CDATA[surveys]]></category>
		<category><![CDATA[VR]]></category>
		<category><![CDATA[worldmapper]]></category>
		<guid isPermaLink="false">https://optional.is/required/?p=9427</guid>

					<description><![CDATA[A double weeknote: We mostly spent it on Gulleggið competition slides, but managed to get a bit more stuff in too.
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Week #781</h2>



<p>On Friday and Saturday, there is the UTMessan tech conference here in Reykjavik. We&#8217;re not directly involved, but indirectly we&#8217;re helping the <a href="https://worldmapper.org">Worldmapper</a> team with some VR maps. On Tuesday, we meet-up for the afternoon to plan what sample of cartograms to use. Our goal is to create two deliverables: an AVP app that puts you in the center of a sphere with the map projected on the inside of it and a equirectangular video playable in a Meta Quest VR headset that loops through a selection of maps.</p>



<p>To do al this, we got down and dirty with DaVinci Resolve. You can create a bunch of nodes which transform and augment the input into new output. We are making the flat cartogram into a sphere and adding additional text and logos that warp correctly with the designed output.</p>



<div class="banner"><img decoding="async" src="https://optional.is/required/wp-content/uploads/2026/02/davinci-resolve-worldmapper-1.png" alt="Screenshot of DaVinci Resolve Studio with the world mapper cartogram and node timeline to map it onto a sphere" /></div>



<p>On Tuesday we had morning coffee with another old friend and chatted about projects, work and AI. He&#8217;s got a huge corpus of text that&#8217;s he and his team have written for 15+ years. Now he wants to ask an LLM questions and get a structured response. We had some ideas, so the research began.</p>



<p>On secret project we&#8217;ve been working on had a demo on Wednesday. They met with the co-CEO of the company and demoed our prototype. This is an iOS app that merges both or their products together. There is a lot of fake data in the UI, but the important parts work. They were VERY impressed!</p>



<p>Working with another old friend at Háskóli Íslands, we started in on creating an online solution to a new vocabulary retrieval tool. <a href="https://starlingvr.co.uk">Starling</a> was developed in the UK to help improve vocabulary which in turn improves reading. As part of the grant, the UK works with two other EU countries; Iceland and Estonia. The method is currently done on paper, but much (if not all) could be digitized. So we ran a small spike this week to setup an online thesaurus tool to help teachers find tier 2 words and their tier 1 definitions.</p>



<p>On Friday and Saturday, we went to the Gulleggið master class. Each year there is a start-up competition called Gulleggið (Golden Egg) and we&#8217;ve joined a small, young, enthusiastic team to help them. This isn&#8217;t our first start-up rodeo, but it is their&#8217;s. Our goal is to help with the prototype, guide them in the general direction and answer questions. As part of the competition, we need to submit a 1-minute explainer video and a specific 10-slide slide deck. That&#8217;s due next Thursday.</p>



<h2 class="wp-block-heading">Week #782</h2>



<p>On Monday, we started the next round of parent surveys by sending out emails to all participants. After a few days, on Wednesday we sent the first reminder SMS. We do this partly because the first email is highly-likely to go into spam. SMS catches them on a different band and it really helps the response rate. We&#8217;ll continue with emails, robocalls for another week, then swap the randomly selected guardian and do it again. Finally in the last week, whomever is left below the required response rate will get human phone calls.</p>



<p>Off and on this week we worked on the Gulleggið slide deck. On Tuesday, KLAK, the organization organizing Gulleggið, had an open house to show the slides and get feedback. We went and things were generally positive and the comments were excellent places for us to improve before the Thursday deadline. With some feedback, we finished the slides and sent them in. Next step is to see if we&#8217;re through as one of the top 10 best ideas. There are over 100 teams that showed interest. Many of which didn&#8217;t attend the Master Class. It&#8217;s probably easy to say many will fall at the first hurdle: Do the Slidedeck correctly! Then many ideas won&#8217;t be businesses. If ours is not in the top 10, it&#8217;s not because it&#8217;s a bad deck or bad business idea, there were just 10 better than ours. It&#8217;s been a great experience and had a great time building a small, new team for this. We&#8217;ll see where it takes us.</p>



<p>We&#8217;ve made it a priority to get more local projects. As part of that we&#8217;ve drafted an email to a few close friends letting them know that we&#8217;re making 1-2 days a week open for local projects and to keep their ear to the ground for opportunities. We realized that we also need something to speak for us in our absence, so we updated our <a href="https://optional.is/capable/">capabilities</a> page. It will forever be an ongoing process. Annoyingly, the coolest, most relevant projects we either can&#8217;t talk about or aren&#8217;t in a place to demo yet.</p>



<p>After last week&#8217;s AI coffee conversation, we explored running a local LLM. We managed to setup LM Studio and get an open source model working. Then we downloaded AnythingLLM to setup a RAG vector database of our own articles. We exported all of these articles and imported them into the RAG Database. The resulting queries were; let&#8217;s be generous and say &#8220;horrible&#8221;. We asked it &#8220;How long have we been publishing&#8221; and its response was 02017. We poked it a bit and it agreed that the first article was published in 02009, not 02017. Great, &#8220;So how long have we been writing?&#8221; it&#8217;s response was &#8220;5 years&#8221;. After some more prompting we asked how many years is it between 2026 and 2017? and it said &#8220;10 years&#8221;. We went back and changed some of the text chunking and overlapping parameters and it did better, but it still has a LONG way to go and we have other more pressing tasks and deadlines this week.</p>



<h2 class="wp-block-heading">Bric-à-brac</h2>



<p>This week we got to try <a href="https://www.resolutiongames.com/retrocade">Retrocade</a> in VR. The detail is INSANE! It fakes old CRT monitors, but then also the pepper&#8217;s ghost trick too! The 3D game cabinets are amazing. They feel used, worn and played on. For a few minutes you really forget you&#8217;re not really there.</p>



<iframe width="560" height="315" src="https://www.youtube.com/embed/K18iXAu8qSg?si=RnhgR_gBqYTW1asd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
