<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <title>Eclected</title>
    <link href="https://justin.fargione.net/feed.xml" rel="self" />
    <link href="https://justin.fargione.net" />
    <updated>2023-06-20T21:30:54-04:00</updated>
    <author>
        <name>Justin Fargione</name>
    </author>
    <id>https://justin.fargione.net</id>

    <entry>
        <title>So the website says to the bot, “Let’s play!”</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/so-the-website-says-to-the-bot-lets-play.html"/>
        <id>https://justin.fargione.net/so-the-website-says-to-the-bot-lets-play.html</id>
            <category term="Dexter"/>

        <updated>2021-09-02T17:55:43-04:00</updated>
            <summary>
                <![CDATA[
                    Creativity and fun always win. No one engages with boring content unless forced, and no one champions non-critical technology they don’t enjoy. At Dexter, we learned early and well that the only successful bot is one that delights and surprises its users. Our most successful&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p id="d9f7" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">Creativity and fun always win. No one engages with boring content unless forced, and no one champions non-critical technology they don’t enjoy. At Dexter, we learned early and well that the only successful bot is one that delights and surprises its users. Our most successful in-house creations have always been infused with as much creativity as we can muster. From cocktail makers to <a href="https://press-start.com.au/news/playstation/2018/02/08/god-war-just-got-free-choose-adventure-game-facebook-messenger/" class="fd hg" rel="noopener ugc nofollow">adventure games</a> to bad joke finders, fun always wins.</p>
<p id="b322" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">We want you to flex your creativity with Dexter bots in any way possible. Today we’re launching a new tool to expand your horizons even further: the Dexter Interactive library. You can now bring your conversations out of their corner and into the whole of your website</p>
<figure class="post__image"><img loading="lazy"  src="https://justin.fargione.net/media/posts/13/1SKL7xr0l3fdLCotgijAuiA.gif" alt="An interactive bot in action" width="750" height="651"></figure>
<p id="8386" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">One of the major limitations of bots is that they live in a safe little bubble that doesn’t have much to do with everything else around them. What if you could let a user browse your site from your bot? Or highlight something on the screen as you explain how it works? Maybe make that <a class="fd hg" rel="noopener ugc nofollow" href="https://blog.rundexter.com/chatbots-thank-you-roger-wilco-5afe3b409a86">Space Quest</a> reboot you’ve always wanted? Dexter Interactive is here to help.</p>
<p id="233f" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">The library is open source and <a href="https://github.com/rundexter/dexter-interactive/" class="fd hg" rel="noopener ugc nofollow">well documented</a>. Getting started is as easy as replacing your existing bot snippet with:</p>
<pre class="gp gq gr gs gt is it cm"><span id="8106" class="cg iu iv ds iw b ix iy iz s ja" data-selectable-paragraph="">&lt;script type="text/javascript" src="<a href="https://cdn.jsdelivr.net/npm/@rundexter/dexter-interactive/dist/dexter-interactive.min.js" class="fd hg" rel="noopener ugc nofollow">https://cdn.jsdelivr.net/npm/@rundexter/dexter-interactive/dist/dexter-interactive.min.js</a>"&gt;&lt;/script&gt;</span><span id="f989" class="cg iu iv ds iw b ix jb jc jd je jf iz s ja" data-selectable-paragraph="">&lt;script&gt;<br>dexterInteractive.createInteractiveConfig({<br>  handlers: []<br>  , dexterSettings: {<br>      botId: '' // Example: AABBCC123123<br>      , botTitle: '' // Example: My Best Botty<br>      , baseURL: 'https://bots.rundexter.com'<br>      , url: 'https://rundexter.com/webwidget-beta'<br>  }<br>})</span><span id="7340" class="cg iu iv ds iw b ix jb jc jd je jf iz s ja" data-selectable-paragraph="">&lt;/script&gt;</span></pre>
<p id="7c99" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">Fill in your bot ID and title, hook up a few ways you want to <a href="https://github.com/rundexter/dexter-interactive#creating-handlers" class="fd hg" rel="noopener ugc nofollow">handle messages</a>, and you’re done! You can react to either the actual text of a message or take advantage of the new ^<code class="im jg jh ji iw b">metadata()</code> tag to pass along specific cues:</p>
<pre class="gp gq gr gs gt is it cm"><span id="20e5" class="cg iu iv ds iw b ix iy iz s ja" data-selectable-paragraph="">+ hi<br>- ^metadata({"action": "hello"}) Hi there!</span></pre>
<p id="2282" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">You’d react to the above like so:</p>
<pre class="gp gq gr gs gt is it cm"><span id="0969" class="cg iu iv ds iw b ix iy iz s ja" data-selectable-paragraph="">handler: [<br>  {<br>    metaPath: '0.action', meta: 'hello'<br>    , onMatch: () =&gt; console.log('User said hi')<br>  }<br>]</span></pre>
<p id="7a02" class="hh hi ds hj b hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy hz ia ib ic id ie dl cg" data-selectable-paragraph="">There’s some great <a href="https://dexter-interactive.rundexter.com/" class="fd hg" rel="noopener ugc nofollow">examples</a> for you to check out, with more to come. We can’t wait to see what you make!</p>
            ]]>
        </content>
    </entry>
    <entry>
        <title>A Better Human (topic)</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/a-better-human-topic.html"/>
        <id>https://justin.fargione.net/a-better-human-topic.html</id>
            <category term="Dexter"/>

        <updated>2021-09-02T17:50:42-04:00</updated>
            <summary>
                <![CDATA[
                    Many people use their Dexter bot tell their story via social media chat. By doing so, they change the basic nature of their account’s chat from person-to-person to person-to machine. This is largely a win for the bot’s owner, as the machine can have far&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p id="c26f" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">Many people use their Dexter bot tell their story via social media chat. By doing so, they change the basic nature of their account’s chat from person-to-person to person-to machine. This is largely a win for the bot’s owner, as the machine can have far longer conversations with far more people far more efficiently than a human (or even a team of humans) ever could.</p>
<p id="0379" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">There are times, of course, when a machine can’t fully substitute for the adaptability and breadth of a conversation between two real human brains. If the people behind your account have the staff and patience to lend your bot an occasional human counterpart, Dexter has always been ready to help you step up and provide that service.</p>
<p id="7d47" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">We have 2 tools to help a human step into your conversation. For serious usage, many bot writers choose to take advantage of the <a href="https://rundexter.com/relay/" class="fd ha" rel="noopener ugc nofollow">Relay</a> tool that comes with our <a href="https://rundexter.com/pricing/" class="fd ha" rel="noopener ugc nofollow">Platform</a> and <a href="https://rundexter.com/pricing/" class="fd ha" rel="noopener ugc nofollow">Enterprise</a> plans. Others engineer a special “<a href="http://docs.rundexter.com/writing/advanced/human-mode/" class="fd ha" rel="noopener ugc nofollow">Human mode</a>” section of the bot where their users can choose to wait for an agent to step in for a chat.</p>
<p id="1b2a" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">For human mode bots, there’s a sneaky little UI issue that can creep in when a human doesn’t immediately step into a conversation. Let’s say your bot is Sally’s Pizza, and a user Frank comes to start a detailed discussion on how you should treat the tomatoes in your famous fresh tomato pie. You, however, are busy slinging hundreds of your coal-fired beauties and miss Frank’s question. Frank, understanding that you’re probably busy, closes his browser and promptly forgets he asked the question. The next day, Frank hops back on his chat with your bot to check your hours….but uh oh, your bot doesn’t respond. Radio button silence. Dead macbook air. What happened?</p>
<p id="cb39" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">Well, most of the time Human Mode involves a topic that looks like this:</p>
<pre class="go gp gq gr gs hz ia cm"><span id="f161" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">+ *<br>- &lt;noreply&gt;</span></pre>
<p id="8241" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">That means that, since Frank placed himself in Human mode, he can no longer interact with your bot! Most bot writers understand this possibility and give their users an obvious way out:</p>
<pre class="go gp gq gr gs hz ia cm"><span id="eb23" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">+ human-start<br>- OK, we'll try to get a human to you ASAP.  If you want to stop waiting, just say "exit" and we'll take you back to the main menu.</span><span id="eb28" class="cg ib ic ds id b ie ii ij ik il im ig s ih" data-selectable-paragraph="">+ (exit|stop|menu)<br>- Sorry we couldn't get to you!  I'll take you back to the main menu now. &lt;send&gt; {topic=default} {@ menu}</span></pre>
<p id="399c" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">This isn’t as useful as it could be for Frank, however. Since he came back to the bot later, he probably doesn’t remember exactly what he was doing last time he was there. Then, either through not paying attention to the instructions or having them somehow disappear from his immediate view, he doesn’t know about the “exit” instruction, and is stuck with an unresponsive agent. This is not, as you might imagine, a great experience.</p>
<p id="02e5" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">One fairly simple way around this problem is to remind the user of the instructions occasionally. Our recommended strategy is to keep track of how long the user has been in Human Mode and, after a certain amount of time has passed, use the catch-all to respond with a fresh reminder of the exit instructions. So as to not hold you in suspense, here’s the whole topic that implements this idea:</p>
<pre class="go gp gq gr gs hz ia cm"><span id="dc49" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">// Use this to start the human takeover process<br>// Called from anywhere via {topic=human} {@ human_start}<br>+ human_start<br>- OK, I'll step aside so a human can come in and chat with you. &lt;send&gt; If you get tired of waiting, just say "Back to Bot" and I'll take you back to the main menu. &lt;call&gt;setHumanStart&lt;/call&gt; ^buttons('Back to Bot')</span><span id="74fe" class="cg ib ic ds id b ie ii ij ik il im ig s ih" data-selectable-paragraph="">// Tell the user to call this to get back to the regular bot<br>+ back to [the] bot<br>- Welcome back! &lt;set human_start&gt; {topic=default} {@ menu}</span><span id="9ad6" class="cg ib ic ds id b ie ii ij ik il im ig s ih" data-selectable-paragraph="">// This is what kills the bot's response while a human is talking<br>// to the user. It mostly means the bot won't respond at all, but <br>// after a certain amount of time it'll remind the user that<br>// they're still waiting for a human.<br>+ *<br>* &lt;call&gt;isStuckInHumanTopic&lt;/call&gt; == true =&gt; Hi there!  You're still waiting for a human to get back to you.  If you get tired of waiting, just say "Back to Bot"! &lt;call&gt;setHumanStart&lt;/call&gt; ^buttons('Back to Bot')<br>- ^bypass()</span><span id="534a" class="cg ib ic ds id b ie ii ij ik il im ig s ih" data-selectable-paragraph="">// Set up a time when the user last heard from the bot.<br>// We'll use this to see if we need to remind them how to exit. <br>&gt; object setHumanStart javascript<br>rs.setUservar(rs.currentUser(), 'human_start', Date.now())<br>&lt; object</span><span id="47c7" class="cg ib ic ds id b ie ii ij ik il im ig s ih" data-selectable-paragraph="">// Check and see if the user is stuck in the topic based on<br>// how long it's been since the bot last chatted with them.<br>&gt; object isStuckInHumanTopic javascript<br>// Get when we started waiting for a human<br>var started = rs.getUservar(rs.currentUser(), 'human_start', Date.now())<br>  // Let the caller give a specific age they want to use and default to 5 minutes otherwise.  Change this to change the wait time.<br>  , waitFor = args[0] || 1000 * 60 * 5<br>;<br>// We're only "stuck" in the human topic if we haven't been waiting long<br>return (Date.now() - waitFor) &gt; started;<br>&lt; object</span></pre>
<p id="18f2" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">That’s it! If you want a breakdown of what’s going on, let’s take it chunk-by-chunk:</p>
<pre class="go gp gq gr gs hz ia cm"><span id="9aea" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">+ human_start<br>- OK, I'll step aside so a human can come in and chat with you. &lt;send&gt; If you get tired of waiting, just say "Back to Bot" and I'll take you back to the main menu. &lt;call&gt;setHumanStart&lt;/call&gt; ^buttons('Back to Bot')</span></pre>
<p id="db5f" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">This is the standard Human Mode intro, explaining to the user what’s going on and what they should do. There are 2 important features here:</p>
<ul class="">
<li id="bd61" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy in io ip cg" data-selectable-paragraph=""><em class="iq">&lt;call&gt;setHumanStart&lt;/call&gt;</em> We call a macro that remembers when we started waiting for a human</li>
<li id="a25c" class="hb hc ds hd b he ir hg hh hi is hk hl hm it ho hp hq iu hs ht hu iv hw hx hy in io ip cg" data-selectable-paragraph=""><em class="iq">^buttons(‘Back to Bot’)</em> We give the user a clickable way to exit the bot if they want.</li>
</ul>
<pre class="go gp gq gr gs hz ia cm"><span id="3fb1" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">+ back to [the] bot<br>- Welcome back! &lt;set human_start&gt; {topic=default} {@ menu}</span></pre>
<p id="d897" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">Here’s the standard exit, but note that we clear the human_start flag to make sure any future human conversation requests start from a clean slate.</p>
<pre class="go gp gq gr gs hz ia cm"><span id="84da" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">+ *<br>* &lt;call&gt;isStuckInHumanTopic&lt;/call&gt; == true =&gt; Hi there!  You're still waiting for a human to get back to you.  If you get tired of waiting, just say "Back to Bot"! &lt;call&gt;setHumanStart&lt;/call&gt; ^buttons('Back to Bot')<br>- ^bypass()</span></pre>
<p id="29f4" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">This is the big change — we’ve tweaked our usual catch-all-and-kill block so that it constantly checks to see how long the user’s been stuck in this topic. If our macro decides we’ve been waiting too long, it’ll respond with the instructions, then reset the clock so that it’ll again wait before the next reminder.</p>
<pre class="go gp gq gr gs hz ia cm"><span id="958c" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">&gt; object setHumanStart javascript<br>rs.setUservar(rs.currentUser(), 'human_start', Date.now())<br>&lt; object</span></pre>
<p id="6b32" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">A quick-and-dirty macro to capture the current time for later comparison.</p>
<pre class="go gp gq gr gs hz ia cm"><span id="9f21" class="cg ib ic ds id b ie if ig s ih" data-selectable-paragraph="">&gt; object isStuckInHumanTopic javascript<br>var started = rs.getUservar(rs.currentUser(), 'human_start', Date.now())<br>  , waitFor = args[0] || 1000 * 60 * 5<br>;<br>return (Date.now() - waitFor) &gt; started;<br>&lt; object</span></pre>
<p id="aa40" class="hb hc ds hd b he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu hv hw hx hy dl cg" data-selectable-paragraph="">A less quick-and-dirty macro that decides if the user’s ready to see a reminder. We grab the time of our last reminder (started), figure out how long we want to wait before nagging (waitFor), and return true if we’ve been waiting long enough.</p>
            ]]>
        </content>
    </entry>
    <entry>
        <title>PA vote objections</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/pa-vote-objections.html"/>
        <id>https://justin.fargione.net/pa-vote-objections.html</id>
            <category term="Politics"/>

        <updated>2021-09-16T10:22:36-04:00</updated>
            <summary>
                <![CDATA[
                    To anyone like me who didn't know what prompted the objection to the Pennsylvania vote last night, here's what it seemed to be about. In 2019, PA updated their election code, in part to expand mail-in-voting rights. This is only the second time the new&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x c1et5uql ii04i59q">
<div dir="auto">To anyone like me who didn't know what prompted the objection to the Pennsylvania vote last night, here's what it seemed to be about. In 2019, PA updated their election code, in part to <a href="https://www.pacounties.org/GR/Documents/Act%2077%20-%20Election%20Reform%20Bill%20summary.pdf?fbclid=IwAR0_s8oNKno78EWWVPAnEkNZPVoASIGu1EuRXCvfbXCbZheL_r-Xp7DrCqU" target="_blank" rel="noopener noreferrer">expand mail-in-voting rights</a>.</div>
<div dir="auto"> </div>
<div dir="auto"><span style="color: var(--text-editor-body-color); font-family: var(--font-base); font-size: inherit; font-weight: var(--font-weight-normal);">This is only the second time the new laws have been in use, and some of the rough edges haven't been smoothed over. Two dates in the law came into conflict this time around. First, requests for mail-in ballots have to be in the county's hands a week before the election. Second, they're not allowed to be submitted after election day.</span></div>
</div>
<div class="o9v6fnle cxmmr5t8 oygrvhab hcukyx3x c1et5uql ii04i59q">
<div dir="auto">With massive disruptions to the post office's operations this year, that 1-week window between the ballot request and submission was far too small. It seemed likely that late but legal submissions would arrive after election day and wouldn't be counted. The problem was <a href="https://apnews.com/.../tom-wolf-pennsylvania-elections..." target="_blank" rel="noopener noreferrer">presented to the state supreme court,</a> <span style="color: var(--text-editor-body-color); font-family: var(--font-base); font-size: inherit; font-weight: var(--font-weight-normal);">who <a href="https://apnews.com/article/election-2020-pennsylvania-lawsuits-elections-philadelphia-0f0e6f48361df96d2d74d68ac6838709?fbclid=IwAR2OybtBeck6FUFFQhHXSt0-JDhIL7MqL21wfWk_khgxPuS1ATSBhC8SjIw" target="_blank" rel="noopener noreferrer">extended the valid deadline of votes by 3 days.</a></span></div>
<div dir="auto"> </div>
</div>
<div class="o9v6fnle cxmmr5t8 oygrvhab hcukyx3x c1et5uql ii04i59q">
<div dir="auto">Last night, objectors claimed that the court's ruling changed the law (a power of the legislature) instead of simply interpreting it (a power of the judiciary). It's not an unreasonable concern in theory, but it's not clear if it actually applies here. Its survival of multiple challenges strongly suggests it doesn't. <span style="color: var(--text-editor-body-color); font-family: var(--font-base); font-size: inherit; font-weight: var(--font-weight-normal);">I didn't see any references to how many votes were actually impacted by the ruling.</span></div>
</div>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Chatbots: Thank you, Roger Wilco!</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/chatbots-thank-you-roger-wilco.html"/>
        <id>https://justin.fargione.net/chatbots-thank-you-roger-wilco.html</id>
            <category term="Dexter"/>

        <updated>2023-06-20T21:30:54-04:00</updated>
            <summary>
                <![CDATA[
                    It’s no great secret that our current exploration of chatbot technology is merely a short step on the long road of conversational interfaces. From the humble cassette-based voicemail machine to Microsoft’s socially challenged twitterbot Tay, automation of human communication has always been a powerful —&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p>It’s no great secret that our current exploration of chatbot technology is merely a short step on the long road of conversational interfaces. From the humble cassette-based voicemail machine to <a href="https://en.wikipedia.org/wiki/Tay_(bot)#Initial_release">Microsoft’s socially challenged twitterbot Tay</a>, automation of human communication has always been a powerful — and sometimes entertaining — enterprise.<br><br>Early video games capitalized on both of these features. My first experience with a computer game was with <a href="https://en.wikipedia.org/wiki/Colossal_Cave_Adventure">Colossal Cave Adventure</a>, a simple text-based game of exploration and discovery. There was no on-screen visualization of the world in which you traveled — Adventure painted pictures in prose and expected you to respond in kind. “You’re at the edge of a forest with a path to the north, and your farm is behind you to the south.” Go north! “You’re in a forest….” The interface was simple and effective, and the resulting experience was powerful enough to inspire entire genres of other games.</p>
<figure class="post__image" ><img loading="lazy" src="https://justin.fargione.net/media/posts/16/1-Txv_8JIrOv7umyBfPCaXbA.gif" alt="Co" width="729" height="410">
<figcaption >Colossal Cave Adventure</figcaption>
</figure>
<p>Other games explored different conversation systems. In the heart of the <a href="https://en.wikipedia.org/wiki/Ultima_(series)">Ultima series</a>, you could chat with any in-game character that wasn’t trying to kill you. Friendly characters might say hi and prompt you to respond, but otherwise, you were left to your own guesswork on how to continue. You quickly learn to ask everyone about their “Job”, and that they <em>will not stop talking to you</em> unless you politely say “Bye”. Each character could respond to a certain subset of topics, some of which would present themselves clearly in conversation, while others must be inferred from your growing knowledge of the world.</p>
<figure class="post__image" ><img loading="lazy" src="https://justin.fargione.net/media/posts/16/1-JiVAjraOazokKY7vm55-vQ.gif" alt="Ultima: Martian Dreams" width="640" height="400">
<figcaption >Ultima: Martian Dreams</figcaption>
</figure>
<p>The true masters of the conversational game lived at <a href="https://en.wikipedia.org/wiki/Sierra_Entertainment">Sierra On-Line</a>. Creators of the famous <a href="https://en.wikipedia.org/wiki/King%27s_Quest">King’s Quest</a>, <a href="https://en.wikipedia.org/wiki/Space_Quest">Space Quest</a>, and <a href="https://en.wikipedia.org/wiki/Leisure_Suit_Larry">Leisure Suit Larry</a> series, Sierra games were conversational from the very beginning. Walk your character up to a locker and “Look at the locker” — why, the locker is closed! “Ok, open the locker” A bottle of shampoo drops to the floor. “Take the shampoo” You’re half ready for your shower!</p>
<figure class="post__image"><img loading="lazy"  src="https://justin.fargione.net/media/posts/16/1-E1ODGdlU1WOp91UHy3bERg.gif" alt="Space Quest 2" width="640" height="367"><figcaption>Space Quest 2</figcaption></figure>
<p><br>Every time you popped a new Sierra game into your high-end, double density floppy drive, you immediately began to test the edges of its language skills. Weird requests, curse words, innuendo…it was fun to explore what a computer could and could not understand. No strangers to humor, the authors at Sierra anticipated a great deal of this behavior, resulting in a bevy of appropriate easter egg responses. “Take leak” was always good for a giggle, even when no onions were around.<br><br>Sierra managed to build conversational engines in 1980 that not only spawned a decade’s worth of hit games, but also predicted much of the technology we currently leverage for creating bots. Let’s take a look at how they implemented some modern concepts in AGI (the Adventure Game Interpreter) 36 years ago, and see how it stacks up against SuperScript, a modern bot development platform.</p>
<h3>Topics</h3>
<p>When building chatbots, related parts of a conversation get organized into topics. There’s no jumping from subject to subject without a specific transition, just like there shouldn’t be in a sane and sober human conversation.<br><br>In SuperScript, topics are separate scripts that contain a collection of related “gambits” — conversational pairs of user requests and bot responses. To change the scope of the conversation, a gambit must redirect the user to a separate topic. Talking about Robot Wars? Say “I’m tired of robots. Can we talk about Full House instead?” and a smart script will take you a new — and less interesting — topic.<br><br><code>&gt; topic:keep old_games (games, non-millenials)//Provide a clue if we don't understand the request</code><br><code>+ *</code><br><code>- I hear you like old games - have you tried Leisure Suit Larry?//Give a simple response if they're fans</code><br><code>+ * (like|love) Leisure Suit Larry*</code><br><code>- Careful, he might love you back!//If they profess a love for a lesser game, respond with some snark,</code><br><code>//then send them to a topic that might be more appropriate for them</code><br><code>+ * (like|love) Pokemon*</code><br><code>- Uhm...yeah, sure, that's an old game.  (cough).  </code><br><code>^topicRedirect(millenials)</code><br><code>&lt; topic</code><br><br>In AGI, scope is defined by a more “physical” boundary: the room that your character currently occupies. Each room carries its own set of definitions, gambits, and other scripts. If you try to “light the stove” in the bathroom, AGI won’t know what you’re talking about, but in the kitchen you’ll see little red pixels of fire spring up. Global scripts and gambits can be #included in any room, giving authors the flexibility to share data and conversations between rooms.<br><br>To change scope, simply walk your character into a different room.<br><br><code>//woods.txt</code><br><code>if(said('take', 'mushroom')) {</code><br><code>    print('You pluck a mushroom from the rotten log');</code><br><code>}//basement.txt</code><br><code>if(said('take', 'mushroom')) {</code><br><code>    print('You brace the window to prevent the purple elephant from flying into your cerebellum and stealing your Cheetos');</code><br><code>}</code></p>
<h3>Triggers</h3>
<p>Every time a user sends a request, it gets checked against a series of triggers. When the request matches a trigger, the response associated with that trigger is returned. These pairs are called gambits. They’re the guts of a good chat system.<br><br>In SuperScript, triggers are complex, powerful things. They can range from simple exact matches:<br><br><code>+ Hi there!</code><br><code>- Hello!</code><br><br>to wildcard matches:<br><br><code>+ What do you think of *?</code><br><code>- I love &lt;cap&gt;!</code><br><br>to full-blown, natural-language-tool-fueled, english-degree-justifying structures:<br><br><code>+ Why is my ENTY:animal &lt;verb&gt; a &lt;noun&gt; at me?</code><br><code>- Maybe if you remembered to feed it from time to time this wouldn't be a problem....</code><br><br>Even more, you can make rough conceptual matches using the built in <a href="https://wordnet.princeton.edu/">WordNet english language lexicon</a>:<br><br><code>+ Is a ~canine a doge? #(matches dog, canine, dalmation, etc.)</code><br><code>- &lt;cap&gt; is SO doge!  Wow!</code><br><br>This is where modern technology has left AGI well behind. Just including the WordNet database would have caused the original King’s Quest to take up at least 35 floppy disks, and you would have had to load and empty your system’s memory 88 times in order to read it all. We won’t even discuss the impossibility of the increased processing power required.<br><br>However, AGI did have a limited, yet clever, strategy for performing simplistic NLP. Games were distributed with a WORDS.TOK file that acted like a manually generated WordNet conceptual matcher. For each word you wanted to use in your trigger (“counter”), you could add a group of matching words (“countertop”, “cabinet”, “shelf”, “island”).<br><br>In an actual “gambit”, the string() function was used to find word matches inside the input. string(“get”, “knife”, “counter”) would then match “Get the cleaver off the island”, “Take the blade from the shelf”, and maybe even “Grab the stabbystabber from the boxtopthing.”<br><br><code>// WORDS.TOK</code><br><code>bae | smh | yolo | fleek =&gt; millennial</code><br><code>// grade_school.txt</code><br><code>if(string('say', 'millennial')) {</code><br><code>    print("I didn't understand a word you just said...");</code><br><code>}</code><br><br>What’s more, AGI was a full-fledged scripting language, so it could even do things that would be difficult or impossible in SuperScript:<br><br><code>//political_convention.txt</code><br><code>#define has_head_trauma f100if(say('listen', 'debate')) {</code><br><code>   if(has_head_trauma) {</code><br><code>       print('This all makes total sense!');</code><br><code>   } else {</code><br><code>       print('Their lips are moving, but all that comes out ');</code><br><code>       print('is darkness and disappointment');</code><br><code>    }</code><br><code>}</code><br><code>if(say('bang', 'head', 'wall')) {</code><br><code>   set(has_head_trauma);</code><br><code>}</code></p>
<h3>Responses</h3>
<p>Language generation is an area that doesn’t seem to have progressed very well in 35 years. Replies in both SuperScript and AGI are simple systems that combine plain text with the occasional piece of captured data. SuperScript adds the ability to make replies bounce the user between topics, while AGI can take advantage of its full scripting capabilities to tweak responses.<br><br><code>//SuperScript</code><br><code>+ Hello</code><br><code>- Hi</code><br><code>- Don't you have anything better to do?</code><br><code>- I SAID HI! ^topic_redirect(grumpy_bot)//AGI</code><br><code>#define response 1</code><br><code>if(say('hello')) {</code><br><code>    if(equaln(response, 1)) {</code><br><code>        print('Hi');</code><br><code>    } else if(equaln(response, 2)) {</code><br><code>        print("Don't you have anything better to do?");</code><br><code>    } else {</code><br><code>        print("I give up.");</code><br><code>    }</code><br><code>    increment(response);</code><br><code>}</code></p>
<h3>Where are we now?</h3>
<p>After 1990, Sierra moved from text to simpler icon-based actions in order to make their games feel more approachable.</p>
<figure class="post__image" ><img loading="lazy" src="https://justin.fargione.net/media/posts/16/1-FcgBnuLkSSobhH9BnNmf9w.gif" alt="Space Quest 5" width="639" height="400">
<figcaption >Space Quest 5</figcaption>
</figure>
<p>Sadly, the entire industry followed suit, and modern games gradually moved away from conversational interfaces. Open-ended inputs were traded for choose-your-own-adventure style canned text, and now have been further simplified with radial-style clickers.</p>
<figure class="post__image" ><img loading="lazy" src="https://justin.fargione.net/media/posts/16/1-EClyo22s8VoIRVa2u2q2Kg.webp" alt="Mass Effect" width="720" height="516" sizes="(max-width: 48em) 100vw, 768px" srcset="https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-xs.webp 300w ,https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-sm.webp 480w ,https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-md.webp 768w ,https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-lg.webp 1024w ,https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-xl.webp 1360w ,https://justin.fargione.net/media/posts/16/responsive/1-EClyo22s8VoIRVa2u2q2Kg-2xl.webp 1600w">
<figcaption >Mass Effect</figcaption>
</figure>
<p>Text-based games did live on past the heyday of AGI in some places, such as online Multi-User Dungeons (MUDs), although they, too, are a dying breed:</p>
<figure class="post__image"><img loading="lazy"  src="https://justin.fargione.net/media/posts/16/1-ncrxiSdws75M7_9mlr0x1w.webp" alt="MUD" width="720" height="540" sizes="(max-width: 48em) 100vw, 768px" srcset="https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-xs.webp 300w ,https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-sm.webp 480w ,https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-md.webp 768w ,https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-lg.webp 1024w ,https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-xl.webp 1360w ,https://justin.fargione.net/media/posts/16/responsive/1-ncrxiSdws75M7_9mlr0x1w-2xl.webp 1600w"><figcaption>MUD</figcaption></figure>
<p>Even the prolific indie game community seems to shy away from conversational interfaces. There was one heroic effort to build a conversationally driven game in 2005 called <a href="http://www.interactivestory.net/">Facade</a> which was hailed as the “Future of video games”. That future never arrived.</p>
<figure class="post__image"><img loading="lazy"  src="https://justin.fargione.net/media/posts/16/1-aXNq1t1J9gqbBjnvxZnOsQ.webp" alt="Facade" width="720" height="497" sizes="(max-width: 48em) 100vw, 768px" srcset="https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-xs.webp 300w ,https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-sm.webp 480w ,https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-md.webp 768w ,https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-lg.webp 1024w ,https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-xl.webp 1360w ,https://justin.fargione.net/media/posts/16/responsive/1-aXNq1t1J9gqbBjnvxZnOsQ-2xl.webp 1600w"><figcaption>Facade</figcaption></figure>
<p>However, thanks to the current Bot craze, momentum has returned to conversational interface design. As we gain understanding in how best to use and design such interfaces, and as we design better and more efficient tools, maybe an ambitions game developer will figure out how to realize a powerful, modern, chat-based game.<br><br>Or maybe I’ll just rebuild Colossal Cave Adventure in Dexter.</p>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Mahjongg and Me</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/mahjongg-and-me.html"/>
        <id>https://justin.fargione.net/mahjongg-and-me.html</id>
            <category term="Ancient History"/>

        <updated>2021-09-02T17:21:16-04:00</updated>
            <summary>
                <![CDATA[
                    Ever since switching my primary development machine over to Ubuntu, I’ve developed a nasty habit of firing up Mahjongg every time I have to watch logs or wait for a task to run for any great length of time. Even for an old, jaded gamer,&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p>Ever since switching my primary development machine over to Ubuntu, I’ve developed a nasty habit of firing up Mahjongg every time I have to watch logs or wait for a task to run for any great length of time.  Even for an old, jaded gamer, it’s a surprisingly fun and challenging quasi-distraction: just engaging enough to keep me from feeling bored, and not so engrossing that I lose track of the logs flying by on my second monitor.</p>
<p>Just because you can’t have too many justifications for newfound distractions, I also realized that the game teaches a very valuable lesson for startup types, programmers in particular.  For those not familiar with mahjongg, the goal is to remove exposed tiles in matched pairs from a specially shaped stack.  There are four of each type of tile, so throughout the game you’ll have several options of which of the four to remove as pairs.  The real trick is that every time you remove the first two of four tiles, you’re critically limiting your furture pair matching ability for that set, since now you -must- pair the remaining two.</p>
<p>A player in this kind of environment learns several important things.  First, you cannot play safe - there’s no way to win the game by leaving all your options open, and crafty stacks obscure difficult challenges you may face in the future.  Therefore you must play smart, and you play smart by only making moves that make a future move possible.  Each pair removed should expose one or more tiles you -know- you’ll need for a move in the future…removing pairs just for the sake of their removal often causes you to lose the game.</p>
<p>This is also a sound strategy for a startup.  You start your company early with a whole world of options in front of you, but resources to only pursue a few.  Pursuit of one option often removes several others, and so each step you take should set up one or more future moves.  Randomly exploring possibilities will, more often than not, ultimatley prevent you from reaching your goal.</p>
<p>For startup programmers, this lesson is all the more poingiant.  There are always libraries, routines, and architecture that require our attention, and we lack the resources to merely peruse our to-do list until all items are finished.  Instead, we must choose what architecture to make robust for worry-free scalability and which we can hack into place.  If you over-optimize the wrong code, those you neglect will haunt you during your first traffic spike.  We must think three steps ahead to see which routines might benefit from being rolled into a library for better portability and which will survive with judicious copy/paste solutions.  Choose wrong and a future tweak to your logical, not fully realized, will irrecoverably corrupt your data.</p>

            ]]>
        </content>
    </entry>
    <entry>
        <title>Made in USA</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/made-in-usa.html"/>
        <id>https://justin.fargione.net/made-in-usa.html</id>
            <category term="Politics"/>
            <category term="Ancient History"/>

        <updated>2021-09-16T10:22:46-04:00</updated>
            <summary>
                <![CDATA[
                    “Made in USA” is a fascinating phrase. My reaction to seeing it on a product is rather complicated, and can set off little bursts of patriotism, consumerism, elation, disappointment, and confusion. Patriotism sets in first. A little voice in the back of my head that&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="entry-content">
<p>“Made in USA” is a fascinating phrase.  My reaction to seeing it on a product is rather complicated, and can set off little bursts of patriotism, consumerism, elation, disappointment, and confusion.</p>
<p>Patriotism sets in first.  A little voice in the back of my head that strangely sounds like Larry the Cable Guy says “It’s made in Amurrica, not in one o’ them slanty-eyed countries west o’ Nevada!”.  The wake of our economic decline and the swell of the locavore movement (and, I must admit, increased sentimentality in my old age) makes this feeling stronger now than it ever has been before.  This, in turn, leads to …</p>
<p>Consumerism!  Buy, buy, buy!  Do I need it?  Maybe.  But now I have that one extra excuse I need…I should get it now!  Decades of training from advertisers, media, and my peers has made this another frightfully strong urge, one that I have learned to fight only through the strength of mantra “ohm….mygod remember your last credit card statement”.  When the mantra fails, and the purchase is made, we make it to …</p>
<p>Elation!  The product is wonderful, I’m happy I got it, and I’m actually using it!  This does happen occasionally…for instance, the simple Weber kettle grill I got two years ago, despite rare use and heavy neglect, is still immaculately rust-free and ready to do my high-octane bidding at will.</p>
<p>More often, however, the actual next step is a looming sense of disappointment that I squandered my limited resources on a product I’m not using.  For example, look at … err… everything else I own?</p>
<p>Once the roller coaster finishes, I’m generally just plain confused.  The phrase “Made in USA”, while able to evoke powerful emotions, seems poorly defined.  For instance, many products are actually <em>assembled</em> in the USA from parts manufactured overseas.  Kitchenaid, Toyota, and Honda are examples of this category.  Are <em>they</em> made in the USA?  Why aren’t all the interesting products at craft fairs hawking the term…do they have to pay a prohibitive fee to some licensing agency?</p>
<p>The answer is surprisingly practical.  It turns out there aren’t any certifications, licenses, or fees involved in putting the Made in USA logo or phrase on your product, just a carefully structured series of <a title="Complying with the Made in USA Standard: ftc.gov" href="http://business.ftc.gov/documents/bus03-complying-made-usa-standard">requirements that your product must meet</a>.  There’s no proactive enforcement of these rules, but independent watchdogs and pissed-off consumers can rat out companies who don’t comply by calling the FTC’s 1-800-ITS-FAKE line.</p>
<p>Assuming the penalties for non-compliance are sufficiently harsh, this seems like a very practical mechanism…the FTC doesn’t have to spend money actively policing producers, but those producers have to worry that the consumers they’re hoping to lure in with the phrase don’t rat them out.  While I’m sure there’s plenty of ways to get away with breaking the rules (like having an inscrutable production process), so long as it keeps such skullduggery to a minimum, it qualifies as effective to me.</p>
<p>But why doesn’t every crafter and crocheter slap the label on their products?  My guess is that they’re part of the rare, intelligent breed that refuses to associate their products with poor grammar, and “Made in <em>the</em> USA” just doesn’t have the same punch.</p>
</div>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Taming the tempting web</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/taming-the-tempting-web.html"/>
        <id>https://justin.fargione.net/taming-the-tempting-web.html</id>
            <category term="Ancient History"/>

        <updated>2021-09-02T17:31:53-04:00</updated>
            <summary>
                <![CDATA[
                    I live on the web. I work on it, I play on it, I socialize on it. I am, therefore, subject to great temptation to misuse the web, particularly during work. Random browsing and long chains of link-following are very detrimental to productivity, and controlling&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="entry-content">
<p>I live on the web.  I work on it, I play on it, I socialize on it.  I am, therefore, subject to great temptation to misuse the web, particularly during work.  Random browsing and long chains of link-following are very detrimental to productivity, and controlling the impulse that begins such acts is very, very difficult.</p>
<p>Today I finally found a tool that somehow has managed to escape my notice for years: <a href="https://addons.mozilla.org/en-US/firefox/addon/leechblock-ng" title="Addon homepage">LeechBlock</a>.  This tool lets you add your distracting sites to named buckets, each of which you can give a certain number of access rules.  For instance, I have two buckets – Time Wasters and Semi-Time Wasters:</p>
<p><strong>Time Wasters</strong></p>
<p>I identified these as the sites I’d start browse to just by habit, almost out of sheer motor memory.  An instant distraction is all it would take for my mouse to automatically open a browser and start typing one of these addresses:</p>
<ul>
<li>http://reddit.com</li>
<li>http://arstechnica.com</li>
<li>http://newegg.com (why is assembling and configuring systems you’re not going to buy <em>fun</em>??)</li>
</ul>
<p>I set these up so that I can only get them for five minutes an hour during normal business hours, 7 days a week</p>
<p><strong>Semi-Time Wasters</strong></p>
<p>These are sites that I visit somewhat less regularly, or are useful enough in a business sense that I don’t want to completely remove my ability to read them:</p>
<ul>
<li>http://news.ycombinator.com</li>
<li>http://nytimes.com</li>
</ul>
<p>I allow myself 10 minutes per hour on these.</p>
<p>My previous approach to this problem had been to de-route my obsessive sites in windows/system32/drivers/etc/hosts (by pointing them at localhost).  This kept them completely out of my reach, but I was loathe to move the less distracting sites into the scheme as I do get quite a bit of good, marketable information from them.  That meant it was just pure willpower that kept me from reading pages and pages of good content while I should be crushing small, elusive, annoying bugs.  Needless to say, it didn’t always work out well.</p>
<p>The impressive result to he self-denial process is how quickly the motor memory fades.  A few disrupted attempts at redditing is all it takes to make the urge go away.  It’s like the invisible gremlin in my head that was keeping me from working gave up and went home.</p>
</div>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Bye bye bogeyman, and thanks for all the fear</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/bye-bye-bogeyman-and-thanks-for-all-the-fear.html"/>
        <id>https://justin.fargione.net/bye-bye-bogeyman-and-thanks-for-all-the-fear.html</id>
            <category term="Politics"/>
            <category term="Ancient History"/>

        <updated>2021-09-16T10:23:01-04:00</updated>
            <summary>
                <![CDATA[
                    Today an impromptu celebration has swept the country, as a ten year hunt for the apparent mastermind of 9/11 has come to a close. As I write this, my facebook feed is continuously refilling with a variety of congratulatory messages, and the news media is&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="entry-content">
<p>Today an impromptu celebration has swept the country, as a ten year hunt for the apparent mastermind of 9/11 has come to a close.  As I write this, my facebook feed is continuously refilling with a variety of congratulatory messages, and the news media is in a frenzy of reporting and speculation.</p>
<p>Celebrations are certainly in order, but only to a point.  One fact that cannot be forgotten in the general jubilation is that, in a broad sense, Bin Laden won, and will continue to win even after his death.  Look at our airports, where citizens are routinely groped and digitally stripped in the name of security.  Look at our economy, which is straining under the weight of two unending wars.  Look to the top of our political structure, where the executive has accumulated enough power to make our founders seethe in their graves.  Look to our internal security culture, which works to monitor its citizens’ activity without warrant, and who now, under executive order, can assassinate American citizens.</p>
<p>Bin Laden’s death is a long-overdue boon, and we are justified in our celebration.  We must, however, recognize that the war to save America’s identity now needs to begin: we need to put fear behind and begin to remember our values of freedom, respect, and pride.</p>
</div>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Mozilla Prism and Yahoo Mail</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/mozilla-prism-and-yahoo-mail.html"/>
        <id>https://justin.fargione.net/mozilla-prism-and-yahoo-mail.html</id>
            <category term="Ancient History"/>

        <updated>2021-09-02T17:22:05-04:00</updated>
            <summary>
                <![CDATA[
                    For those of you who are not familiar with Mozilla Prism, it's a tool that allows you to sandbox web applications away from the rest of your day-to-day browsing. For security freaks (which we should all be to at least some degree), this is an&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p>For those of you who are not familiar with <a href="https://wiki.mozilla.org/Prism">Mozilla Prism</a>, it's a tool that allows you to sandbox web applications away from the rest of your day-to-day browsing.  For security freaks (which we should all be to at least some degree), this is an excellent tool, as it prevents data from being shared or potentially stolen between web pages.  It also allows you to clear away the browser navigational elements, making the page more like a real application and giving you more screen real estate to work with.</p>
<p>The big problem with Prism right now is that it's in beta and isn't technically Firefox (even though it's the same exact browser engine).  That means software that sniffs the user agent string specifically for certain browsers has no clue what Prism is, and therefore might not let you do everything you could were you in Firefox itself.  Most people come across this issue with YAHOO Mail.  YAHOO's newest mail client is super-sexy, but in order for it to do all the fancy interactivity that it does, it relies on having a very modern, snappy javascript implementation in the browser.  To make sure the user's experience is top notch, it therefore only lets browsers it <i>knows</i> are good enough into the new client, and forces older or unidentifiable browsers into the old, flat client.  Unfortunatley, it does not yet recognize Prism, and therefore your nice YAHOO Mail sandboxes in Prism won't have access to the newer mail client.</p>
<p>In theory, there's a <a href="https://web.archive.org/web/20150224193236/http://www.thingsthemselves.com/webrunner/ymail.webapp" class="externalLink">plugin/template</a> linked to at <a href="https://web.archive.org/web/20150224193236/https://wiki.mozilla.org/prism" class="externalLink">mozilla's prism wiki</a> that is supposed to fix this problem, but it doesn't seem to work as of Prism 1.0 beta 1.  A user named <strong>rotassator</strong> on the Mozilla Lab's forums outlined an <a href="https://web.archive.org/web/20150224193236/https://labs.mozilla.com/forum/comments.php?DiscussionID=1344">excellent alternative solution</a> that I'd like to repeat here for searchers' sake.  Here's how to do it:</p>
<ol>
<li>Create your Yahoo Mail sandbox by running Prism and filling in the form, creating a shortcut in your start menu or on your desktop</li>
<li>Right-click on the shortcut and go to 'properties', then copy the entire contents of the 'target' field to your clipboard.</li>
<li>Goto Start / Run (in XP) and paste this information into the window, then at the end add the text <i>-uri</i> <i>about:config</i></li>
<li>Agree that you're OK voiding your warranty (and don't panic, this isn't a big deal)</li>
<li>Right-click somewhere in the window and goto New / String</li>
<li>Call your new string <i>general.useragent.override</i></li>
<li>Set it to <i>Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 </i>- this will make it look like you're using Firefox 3 on Windows Vista</li>
<li>Close the window and then run the program from your shortcut normally.  You should now be dumped into the new mail client!</li>
</ol>
<p>I hope this helps someone!</p>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Deja Vu - Outlook Email Rendering</title>
        <author>
            <name>Justin Fargione</name>
        </author>
        <link href="https://justin.fargione.net/deja-vu-outlook-email-rendering.html"/>
        <id>https://justin.fargione.net/deja-vu-outlook-email-rendering.html</id>
            <category term="Ancient History"/>

        <updated>2021-09-02T17:21:59-04:00</updated>
            <summary>
                <![CDATA[
                    If anyone hasn't heard, there's a bit of a kerfuffle brewing about Microsoft's decision to continue to use Word as the default editor and html renderer for Outlook 2010. Web developers reading this will probably cringe, as Outlook is the primary thorn in any email&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <p>If anyone hasn't heard, there's a bit of a kerfuffle brewing about Microsoft's decision to continue to use Word as the default editor <em>and html renderer</em> for Outlook 2010. Web developers reading this will probably cringe, as Outlook is the primary thorn in any email designer's side. A case in point: I was hired not too long ago to assemble a tightly-designed email for a small publisher. The design was clean, simple, and attractive. I generated a clean, standards-compliant version fairly quickly, but when I moved to adding compatibility for Outlook, my time and their costs literally tripled.</p>
<p>This sounds all too much like the arguments made against changing standards support in IE6. The IE6 argument started when a Microsoft product was found to handle things in a nonstandard manner that the larger community of developers found troublesome. That argument resulted in the ascension of Firefox and Safari, as well as Microsoft's decision to support better standards in IE7 and 8 later one.</p>
<p>We're now on the second phase of deja vu now, where the Microsoft holds that their method and strategy is fine and proper, even if it breaks their fundamental compatibility with the rest of the community. Now we'll move on to the last phase, where enough of an outcry is generated that a secondary application like Thunderbird or GMail begins to get better PR and market share. Well after this happens, Microsoft will begin to implement better compatibility in order to appease the community and retain their user base.</p>
<p>It's sad that this has to play out again so soon after the IE6 debacle. One would hope that losing 20% of a monopolistic market would be enough of a jolt to change the corporate culture at Microsoft to recognize the importance of standards on the internet, but their <a target="_blank" href="https://web.archive.org/web/20150224193236/http://blogs.msdn.com/outlook/archive/2009/06/24/the-power-of-word-in-outlook.aspx" class="externalLink" rel="noopener">recent declarations</a> indicate otherwise.</p>
<p>Outlook is a digital communications tool, and digital communications rely on standards to operate properly. Despite Microsoft's claim to the contrary, there is a standard for email rendering: HTML 4 and CSS 2. YAHOO, GMail, OSX Mail, Thunderbird, and Hotmail all render consistently using this standard, leaving Outlook as the IE6-like outlier. If they wish to use Word to make the editing portion of their user experience better, that's fantastic, and I encourage them to do so. Simply make the results obey standard HTML/CSS rules, and use a real HTML/CSS renderer to display emails from others.</p>
            ]]>
        </content>
    </entry>
</feed>
