<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Thimbleweed Park 2 dev blog</title>
    <link>https://blog2.thimbleweedpark.com/</link>
    <description>Recent content on Thimbleweed Park 2 dev blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 12 Sep 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog2.thimbleweedpark.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Triggers and Splashing</title>
      <link>https://blog2.thimbleweedpark.com/triggers1/</link>
      <pubDate>Sat, 12 Sep 2026 00:00:00 +0000</pubDate>
      <guid>https://blog2.thimbleweedpark.com/triggers1/</guid>
      <description>&lt;p&gt;David here again!&lt;/p&gt;&#xA;&lt;p&gt;In Thimbleweed Park 1, there was large puddle the actors walked through, and we saw splashing around their feet, and heard splashing for each step. I&amp;rsquo;m going to talk about how we did that by setting up room &lt;code&gt;triggers&lt;/code&gt; and turning on a special animation layer in the actor&amp;rsquo;s animation file.&lt;/p&gt;&#xA;&lt;h2 id=&#34;triggers&#34;&gt;Triggers&lt;/h2&gt;&#xA;&lt;p&gt;In the Dinky engine, triggers are quadrilaterals on the screen, usually placed somewhere in the area where the actors are going to walk. When an actor enters a trigger, the &lt;code&gt;triggerEnter() &lt;/code&gt;function is called, and when they exit the trigger, the &lt;code&gt;triggerLeave()&lt;/code&gt; function is called.&lt;/p&gt;&#xA;&lt;p&gt;Triggers are added using our room setup tool, Wimpy. We add a generic object, indicate it&amp;rsquo;s a trigger, and adjust the four corners of the quadrilateral to match the desired trigger area. More on this below.&lt;/p&gt;&#xA;&lt;h2 id=&#34;animation-layers&#34;&gt;Animation Layers&lt;/h2&gt;&#xA;&lt;p&gt;In my &lt;a href=&#34;https://blog2.thimbleweedpark.com/animation1&#34;&gt;last blog post&lt;/a&gt; on animation, I mentioned we could have multiple layers for things like hats, heads, nose glasses. We also used layers for splashes.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-aseprite-splash.png&#34; style=&#34;width: 75%;&#34;&gt;&#xA;&#xA;&lt;p&gt;In the above screenshot you can see all the layers that make up the basic Agent Ray animation, including one for eye blinks (the blink is made up of a few pixels which cover her eyes), eyes looking left or right, a collection of six heads that each have a different mouth shape (maybe we&amp;rsquo;ll go into lipsync in another blog), and near the bottom, you see the splash layer.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s also a layer near the bottom called &lt;code&gt;_trigger&lt;/code&gt;. This has nothing to do with room triggers, but is a flag we can set to trigger a sound effect (footstep), or some other event we need synchronized with the animation.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;_floor&lt;/code&gt; layer is for reference only, and helps us align the actor to where the floor will be. I have it turned off in the above screen capture.&lt;/p&gt;&#xA;&lt;p&gt;The splash animation is made up of three frames. We position the frames over the actor&amp;rsquo;s feet, timed to the moment the foot hits the ground (or water).&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s the splash animation of Agent Ray.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-walk-splash-right.gif&#34; style=&#34;width: 20%;&#34;&gt;&#xA;&#xA;&lt;h2 id=&#34;trigger-code&#34;&gt;Trigger Code&lt;/h2&gt;&#xA;&lt;p&gt;Now that we have the animation working, here&amp;rsquo;s the code to turn on and off the splash layers on Agent Ray. &lt;code&gt;splashTrigger&lt;/code&gt; is what I named the room trigger in Wimpy:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;splashTrigger = {&#xA;&#x9;function triggerEnter(actor) {&#xA;&#x9;&#x9;footstepsWater(actor)&#xA;&#x9;}&#xA;&#x9;function triggerLeave(actor) {&#xA;&#x9;&#x9;footstepsNormal(actor)&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and elsewhere we have the actual footstep functions:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function footstepsNormal(actor) {&#xA;&#x9;actor.footstep_sound = actor.footstep_save&#xA;&#x9;actorShowLayer(actor, &amp;#34;splash&amp;#34;, false)&#xA;}&#xA;&#xA;function footstepsWater(actor) {&#xA;&#x9;actor.footstep_sound = SOUNDID(footstep_water)&#xA;&#x9;actorShowLayer(actor, &amp;#34;splash&amp;#34;, true)&#xA;}&#xA;&#xA;function footstepsGrass(actor) {&#xA;&#x9;actor.footstep_sound = SOUNDID(footstep_grass)&#xA;&#x9;actorShowLayer(actor, &amp;#34;splash&amp;#34;, false)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each actor has a default footstep, and we save that off in the &lt;code&gt;footstep_save&lt;/code&gt; variable for each actor.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;actorShowLayer&lt;/code&gt; command turns on and off the specified layer.&lt;/p&gt;&#xA;&lt;p&gt;I threw in another function above, &lt;code&gt;footstepsGrass()&lt;/code&gt;, where I was testing out the sound of walking on grass and added another room trigger area over the grass outside the Nickel News.&lt;/p&gt;&#xA;&lt;p&gt;Finally, we have a system function that is called when there&amp;rsquo;s a &lt;code&gt;_trigger&lt;/code&gt; in the animation, as I described above. Again, this is a different kind of trigger from a room-defined trigger quadrilateral. For animation events, the &lt;code&gt;_triggerEvent()&lt;/code&gt; function is called.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function _triggerEvent(actor, event) {&#xA;&#x9;if (event == &amp;#34;@step&amp;#34;) {&#xA;&#x9;&#x9;local sid = actor?.footstep_sound&#xA;&#x9;&#x9;if (sid) {&#xA;&#x9;&#x9;&#x9;playSoundAt(sid, actor)&#xA;&#x9;&#x9;}&#xA;&#x9;} else {&#xA;&#x9;&#x9;if (is_function(actor?.triggerEvent, 1)) {&#xA;&#x9;&#x9;&#x9;actor.triggerEvent(event)&#xA;&#x9;&#x9;}&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The event name in Aseprite for footstep _triggers is &amp;ldquo;@step&amp;rdquo;. If there are other event names in the animation, the &lt;code&gt;else&lt;/code&gt; portion of the code is run, but only if the specified actor has its own &lt;code&gt;triggerEvent&lt;/code&gt; code. For example, the Sheriff from Thimbleweed Park 1 had an animation of flipping a coin, and this is the code that&amp;rsquo;s triggered when that event is detected in his animation:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;function triggerEvent(sound) {&#xA;&#x9;if (sound == &amp;#34;@coinFlip&amp;#34;) playSoundAt(SOUNDID(coin_flip), sheriff)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&amp;rsquo;s what the splash animation looks and sounds like in the game. I don&amp;rsquo;t have a puddle here, but I&amp;rsquo;ve made the trigger quadrilaterals visible for you to see.&lt;/p&gt;&#xA;&#xA;&#x9;&#x9;&#x9;&lt;div&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&lt;iframe&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;src=&#34;https://player.vimeo.com/video/1226069689?dnt=0&#34;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allow=&#34;fullscreen&#34;&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&lt;/iframe&gt;&#xA;&#x9;&#x9;&#x9;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;&amp;ndash; David Fox&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Puzzle Dependency Chart</title>
      <link>https://blog2.thimbleweedpark.com/pdc1/</link>
      <pubDate>Wed, 02 Sep 2026 12:09:41 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/pdc1/</guid>
      <description>&lt;p&gt;Here is the first draft of the Puzzle Dependency Chart for Thimbleweed Park 2.&lt;/p&gt;&#xA;&lt;p&gt;The game is divided into four parts, and this is part 1 (and the simplest part).&lt;/p&gt;&#xA;&lt;p&gt;Still some missing nodes to make some puzzles more complex, but it&amp;rsquo;s a solid first draft.&lt;/p&gt;&#xA;&lt;p&gt;Green nodes are tutorial sections, yellow nodes are flashbacks, and red nodes are TBD nodes that need to be filled out in detail.&lt;/p&gt;&#xA;&lt;p&gt;All sensitive information has been redacted for your protection.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/twp2-pdc1.png&#34;&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.grumpygamer.com/puzzle_dependency_charts/&#34;&gt;How to read Puzzle Dependency Charts&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Podcasts Part 2</title>
      <link>https://blog2.thimbleweedpark.com/podcasts2/</link>
      <pubDate>Sat, 22 Aug 2026 08:39:12 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/podcasts2/</guid>
      <description>&lt;p&gt;Big news. We got someone to help us edit the podcasts. Thanks to everyone who offered support and help.&lt;/p&gt;&#xA;&lt;p&gt;First, the old podcasts are back. You can get them here:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://podcasts.apple.com/us/podcast/thimbleweed-park/id1076754899&#34;&gt;Apple Podcasts&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://open.spotify.com/show/6f37JUBW3AMMDXnrwA7TLQ?si=fd56d3dab9104df7&#34;&gt;Spotify&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://music.amazon.com/podcasts/cacbcad6-6418-4fee-a687-77363d7bde6c/thimbleweed-park&#34;&gt;Amazon Music&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Here is Thimbleweed Park podcast #1 just to get your nostalgia going.&lt;/p&gt;&#xA;&lt;iframe src=&#34;https://play.prx.org/e?uf=https%3A%2F%2Ffeeds.redcircle.com%2Fc2f93a56-100a-4956-b688-578bbec7aa53&amp;ge=452f6ff3-d3dc-42d2-b7dc-b97334b8d25b&amp;ac=3a5a9c&#34;&#xA;&#x9;width=&#34;85%&#34; height=&#34;200&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; allow=&#34;autoplay&#34; loading=&#34;lazy&#34;&#xA;&#x9;style=&#34;display: block; margin: 0 auto;&#34;&gt;&lt;/iframe&gt;&#xA;&#xA;&lt;p&gt;We&amp;rsquo;re going to start up the podcast again as soon as my people talk to David&amp;rsquo;s people and Gary&amp;rsquo;s people talk to my people.  It might be a few weeks to get everything set up.&lt;/p&gt;&#xA;&lt;p&gt;One suggestion I get a lot is wanting to hear from the other team members, so we we&amp;rsquo;ll do that more.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;re also bringing back Friday Questions, so be on the look out for those.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ndash; Ron&lt;/p&gt;&#xA;&lt;p&gt;P.S. I redid the &lt;a href=&#34;https://thimbleweedpark.com&#34;&gt;Thimbleweed Park website&lt;/a&gt; and added a newsletter sign-up. This isn&amp;rsquo;t for new dev blog posts, but larger events and news closer to release.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Animation and Aseprite</title>
      <link>https://blog2.thimbleweedpark.com/animation1/</link>
      <pubDate>Tue, 18 Aug 2026 16:25:17 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/animation1/</guid>
      <description>&lt;p&gt;David here!&lt;/p&gt;&#xA;&lt;p&gt;This is my first blog post for the Thimbleweed Park 2 dev blog, and I hope not the last. I’m going to talk about character animation in the game, a bit about process and tools.&lt;/p&gt;&#xA;&lt;p&gt;In Thimbleweed Park 1 (ok, it was never called that, just Thimbleweed Park, are we retconning the game name?), we used a home-grown (Ron-created) character animation program called Compy. It had some basic features, and emitted json files describing the animation sequences along with the individual cells that could be layered on top of each other to create the character animations you saw in the game. For example, Agent Ray’s body was separate from her head, so while her body was walking, we could independently animate her head and mouth. Likewise we had another layer for eye blinks, another for accessories (hats, nose glasses).&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-aseprite.png&#34; style=&#34;width: 75%;&#34;&gt;&#xA;&#xA;&lt;p&gt;In Return to Monkey Island, our characters were all vector-based, created with the animation tool, Spine. For Thimbleweed Park 2 we’re back to pixel-based characters. Rather than updating Compy, we selected the popular Aseprite for 2D pixel animations ($19.99 on Steam or Aseprite’s website). Ron used it on his recent pixel-based RPG Death by Scrolling, and wanted to stick with it.&lt;/p&gt;&#xA;&lt;p&gt;I learned enough about Aseprite to import some of the animated characters from the first game… a somewhat mind-numbing and tedious task… opening all the frames in the Mac app Preview, then copying/pasting each image into Aseprite’s cell in the timeline. Then apply some magic (Ron’s Python script exportaseprite.py) which exports each animation cell as a PNG, and then packs them into sprite sheets, and keeps track of all the named animation sequences.&lt;/p&gt;&#xA;&lt;p&gt;First spoiler: there are Polaroid cameras in this game just like Thimbleweed Park 1 (opening scene with the agents) and in the Delores standalone game. This time both Agents Ray and Reyes have their own cameras, and we needed more animation sequences than just the right-facing and kneeling photo-taking animation from the first game.&lt;/p&gt;&#xA;&lt;p&gt;In fact, we needed nine sequences… versions for taking photos of low objects, medium height objects, and tall objects. Plus versions for right-facing, back-facing, and front-facing, so 3 x 3 = 9. (When the character faces left we just flip the right-facing animations.)&lt;/p&gt;&#xA;&lt;p&gt;Each animation is made up of multiple short segments, to give us more control of timing. For example, when we want to trigger a sound effect and a screen flash. Octavi took this on as his first project for the game:&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-camera1.gif&#34; style=&#34;width: 50%;&#34;&gt;&#xA;&#xA;&lt;p&gt;Camera out—actor takes the camera out of their jacket, or wherever they magically store it&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-camera3.gif&#34; style=&#34;width: 50%;&#34;&gt;&#xA;&#xA;&lt;p&gt;Camera hold—actor holds the last frame with the camera in position to take the photo&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-camera4.gif&#34; style=&#34;width: 50%;&#34;&gt;&#xA;&#xA;&lt;p&gt;Camera shot—photo is taken as the flash goes off in four frames, and separately we trigger the sound effect and also flash the screen for a quarter of a second&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#x9;&#xA;&#xA;&lt;img loading=&#34;lazy&#34; src=&#34;https://images-grumpygamer.nyc3.digitaloceanspaces.com/ray-camera2.gif&#34; style=&#34;width: 50%;&#34;&gt;&#xA;&#xA;&lt;p&gt;Camera in—camera ejects the photo, actor shakes out the instant photo to dry it off, puts away the camera and returns to a standing position&lt;/p&gt;&#xA;&lt;p&gt;That means our original nine sequences are made up of four segments each, for a total of 36 segments. Fortunately, all elements of each frame were flattened, so we didn’t have separate talking heads, moving eyeballs, etc.&lt;/p&gt;&#xA;&lt;p&gt;To keep this all straight, we used a naming convention and tagged the object to be photographed with low, med, or high, and we also set the actor’s facing in the object (front, right, back). Gathering that information from the object, we knew which animations to trigger:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;camera_out_[low, med, high]_[front, right, back]&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;camera_hold_[low, med, high]_[front, right, back]&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;camera_shot_[low, med, high]_[front, right, back]&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;camera_in_[low, med, high]_[front, right, back]&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Octavi started with the Delores camera animations as a template (from the Delores game), and then created a similar set for Agent Ray. It took a few iterations to get everything perfect. Rather than trying to figure out if it was correct in Aseprite (challenging when there were so many segments to check), I set up a test room so we could check the animations in context… of course I picked the disgustingly gross Thimbleweed Park QuickiePal Bathroom for the photoshoot!&lt;/p&gt;&#xA;&lt;p&gt;The bathroom doesn&amp;rsquo;t appear in Thimbleweed Park 2, but it&amp;rsquo;s finished art and a good test.&lt;/p&gt;&#xA;&#xA;&#x9;&#x9;&#x9;&lt;div&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&lt;iframe&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;src=&#34;https://player.vimeo.com/video/1219121531?dnt=0&#34;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allow=&#34;fullscreen&#34;&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&lt;/iframe&gt;&#xA;&#x9;&#x9;&#x9;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;I didn’t have any targets for a front-facing photo, so I used temp programmer art, then made a QuickTime video and shared it with Octavi.&lt;/p&gt;&#xA;&lt;p&gt;When we looked at the animation in the room, we spotted a few issues. One showed a several-pixel jump from the end of the camera animation to the beginning of the normal standing animation. Once corrected, Octavi then created the same animations for Agent Reyes, and I again sent him a movie for him to confirm all was perfect.&lt;/p&gt;&#xA;&lt;p&gt;For the in-game test interactions, we started with the Delores UI, where the player can drag an inventory object (the camera) out of their inventory and place it over the item to be photographed. Note that the UI in this video is WIP, and will likely go through multiple iterations throughout the development of the game.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ndash; David Fox&lt;/p&gt;&#xA;&lt;p&gt;P.S.&lt;/p&gt;&#xA;&lt;p&gt;We have the following .aseprite files&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;animation/Reyes-base.aseprite&#xA;animation/Reyes-camera.aseprite&#xA;animation/Reyes-climbing.aseprite&#xA;animation/Reyes-reaches.aseprite&#xA;animation/Reyes-toilet.aseprite&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And in the Dinky code we do this&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;default_costume = [ &amp;#34;animation/Reyes-base&amp;#34;,&#xA;                    &amp;#34;animation/Reyes-reaches&amp;#34;,&#xA;                    &amp;#34;animation/Reyes-climbing&amp;#34;,&#xA;                    &amp;#34;animation/Reyes-camera&amp;#34;,&#xA;                    &amp;#34;animation/Reyes-toilet&amp;#34; ]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That adds all the .aseprite animations to a single animated sprite. Then we run this code when taking a picture.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;local position = match(getvalue(subject?.photo_reach)) {&#xA;    REACH_HIGH: &amp;#34;high&amp;#34;&#xA;    REACH_LOW: &amp;#34;low&amp;#34;&#xA;    default: &amp;#34;med&amp;#34;&#xA;}&#xA;local anim = playAnimation(selectedActor, &amp;#34;camera_out_&amp;#34;+position)&#xA;breakwhileanimation(selectedActor, anim)&#xA;anim = playAnimation(selectedActor, &amp;#34;camera_hold_&amp;#34;+position)&#xA;if (is_function(subject?.startTakingPhoto)) {&#xA;    subject.startTakingPhoto(subject.photo)&#xA;}&#xA;breakwhileanimation(selectedActor, anim)&#xA;anim = playAnimation(selectedActor, &amp;#34;camera_shot_&amp;#34;+position)&#xA;playSound(SOUNDID(take_photo))&#xA;breaktime(0.2) // wait a beat to let the sound sync better with the animation&#xA;overlayFlashColor(COLOR_WHITE, 0.25)&#xA;breakwhileanimation(selectedActor, anim)&#xA;anim = playAnimation(selectedActor, &amp;#34;camera_in_&amp;#34;+position)&#xA;breakwhileanimation(selectedActor, anim)&#xA;actorStand(selectedActor)&#xA;if (is_function(subject?.doneTakingPhoto)) {&#xA;    subject.doneTakingPhoto(subject.photo)&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Podcasts</title>
      <link>https://blog2.thimbleweedpark.com/podcasts/</link>
      <pubDate>Wed, 12 Aug 2026 15:53:50 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/podcasts/</guid>
      <description>&lt;p&gt;David, Gary and I really enjoyed doing the Thimbleweed Park 1 podcast and want to continue it for Thimbleweed Park 2, but there are a couple of issues.&lt;/p&gt;&#xA;&lt;p&gt;First is where to host.  I&amp;rsquo;m not a consumer of podcasts, so I don&amp;rsquo;t know all the ins-and-outs. I assume Dropbox isn&amp;rsquo;t a good idea.&lt;/p&gt;&#xA;&lt;p&gt;The Thimbleweed Park 1 podcast was hosted on SoundCloud and for reason I don&amp;rsquo;t fully remember I had a free account, but a few years ago they started charging me so I pull them all down and saved them so I can re-post later.&lt;/p&gt;&#xA;&lt;p&gt;For Thimbleweed Park 2 we need to find a place to host that 1) Doesn&amp;rsquo;t charge a lot of money and 2) doesn&amp;rsquo;t insert ads in the middle. I also don&amp;rsquo;t want to have to upload them to 5 different places, I want one place that all podcast apps can read from.&lt;/p&gt;&#xA;&lt;p&gt;The second issue is they took a lot of time. It basically ate up half of my Saturday recording and editing, prepping, and uploading the podcast.&lt;/p&gt;&#xA;&lt;p&gt;We need to find someone that will take on that job (paid). I&amp;rsquo;m not asking for volunteers so please don&amp;rsquo;t suggest yourself unless it is literally your day job.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;d also like to upload them to YouTube, not as video podcasts, but just audio and maybe an pixel image of each of us when we are talking.&lt;/p&gt;&#xA;&lt;p&gt;There are few (physics) podcasts I listen to that do this. It works well for me.&lt;/p&gt;&#xA;&lt;p&gt;Stay tuned and we hope to start recording in the next month or so. Lots of fun design stuff to talk about.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Thimbleweed Park Engines</title>
      <link>https://blog2.thimbleweedpark.com/twp2_tech/</link>
      <pubDate>Sat, 08 Aug 2026 09:40:33 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/twp2_tech/</guid>
      <description>&lt;p&gt;A few people have asked what the difference with the engine we used for Thimbleweed Park 1 and what we are using for Thimbleweed Park 2.&lt;/p&gt;&#xA;&lt;p&gt;They are basically two different engines with a few similarities, mostly in the format of the room images.&lt;/p&gt;&#xA;&lt;p&gt;Thimbleweed Park 1 used SDL for graphics and sound and a scripting language called &lt;a href=&#34;http://squirrel-lang.org&#34;&gt;Squirrel&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Squirrel is a good language, but it couldn&amp;rsquo;t do the code optimizing I wanted and was missing a few convenience features.&lt;/p&gt;&#xA;&lt;p&gt;You had to ship your game with full source and it compiled it at run-time. I wanted it to emit byte code so I could run an optimization pass.&lt;/p&gt;&#xA;&lt;p&gt;After Thimbleweed Park 1 I started working on a early version of &lt;a href=&#34;https://store.steampowered.com/app/3773590/Death_by_Scrolling/&#34;&gt;Death by Scrolling&lt;/a&gt; (called Runner back then) and in a fit of insanity I wrote a new scripting language called Dinky. It compiled to byte-code and had an optimization pass. It  was still 80% compatible with Squirrel, but I added some new features and it was a lot faster.&lt;/p&gt;&#xA;&lt;p&gt;About this time the idea of &lt;a href=&#34;https://store.steampowered.com/app/2060130/Return_to_Monkey_Island/&#34;&gt;Return to Monkey island&lt;/a&gt; was starting to become real so I started (with David&amp;rsquo;s help) the game &lt;a href=&#34;https://store.steampowered.com/app/1305720/Delores_A_Thimbleweed_Park_MiniAdventure/&#34;&gt;Delores&lt;/a&gt;. It was going to serve as a test bed for porting Thimbleweed Park 1 to my new engine that we&amp;rsquo;d use for Return to Monkey Island.&lt;/p&gt;&#xA;&lt;p&gt;Thimbleweed Park 1 used the SDL sound engine which is very limited and porting to mobile and consoles required re-writing the sound engine.  I initially poo-poo&amp;rsquo;d using FMOD because it would cost $6000 to use it for Thimbleweed Park 1, but in the end I spent more than $6000 porting to all the different platforms. Penny-wise, pound-foolish.&lt;/p&gt;&#xA;&lt;p&gt;So Delores used FMOD and it&amp;rsquo;s a dream.&lt;/p&gt;&#xA;&lt;p&gt;I also teamed up again with Derek who I had worked with on &lt;a href=&#34;https://store.steampowered.com/app/18040/DeathSpank/&#34;&gt;DeathSpank&lt;/a&gt; and he removed SDL and began a new graphics back-end that would use Vulkan, Metal, DirectX, etc. It would make porting to other platforms a lot easier and allow for better use of shaders.&lt;/p&gt;&#xA;&lt;p&gt;We started Return to Monkey Island and basically used the Delores Engine. The big change we had to make was supporting hires images. It was just scaling the rendering, but we had to add a lot of smart caching because the texture were a lot bigger than pixel art.&lt;/p&gt;&#xA;&lt;p&gt;I then started working on Death by Scrolling again and used the Return to Monkey Island engine with a new tile map renderer.&lt;/p&gt;&#xA;&lt;p&gt;Death by Scrolling shipped and then Thimbleweed Park 2 became a reality.&lt;/p&gt;&#xA;&lt;p&gt;Back to the Return to Monkey Island engine.  The changes were pretty simple since we just need to scale it for pixel art again.&lt;/p&gt;&#xA;&lt;p&gt;The big changes were in the Dinky scripting code since I want to re-look at the UI and verbs. I wasn&amp;rsquo;t happy with Thimbleweed Park 1, Delores or Return to Monkey Island and wanted to try something new, kind of a hybrid between the best of the three.&lt;/p&gt;&#xA;&lt;p&gt;But more on that later&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;So, it&amp;rsquo;s a very different engine.&lt;/p&gt;&#xA;&lt;p&gt;Thimbleweed Park 1 -&amp;gt; Runner -&amp;gt; Delores -&amp;gt; Return to Monkey Island -&amp;gt; RPGTBD -&amp;gt; Death by Scrolling -&amp;gt; Thimbleweed Park 2 -&amp;gt; TBD&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>First Post</title>
      <link>https://blog2.thimbleweedpark.com/first_post/</link>
      <pubDate>Sat, 01 Aug 2026 09:53:37 +1200</pubDate>
      <guid>https://blog2.thimbleweedpark.com/first_post/</guid>
      <description>&lt;p&gt;Welcome to the all new Thimbleweed Park 2 dev blog.&lt;/p&gt;&#xA;&lt;p&gt;The response to &lt;a href=&#34;https://www.grumpygamer.com/twp2_announce/&#34;&gt;our announcement&lt;/a&gt; has been overwhelming. Thanks so much for your enthusiasm. It keeps us going.&lt;/p&gt;&#xA;&lt;p&gt;We hope to post at least once a week with all the happenings but no spoilers.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;d like to get the podcast going again, but no promises. It was a lot of work each week.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll post updates on Mastodon or you can use RSS like it&amp;rsquo;s 2004 or you can hit refresh obsessively.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;d like to do Big Box versions, but we&amp;rsquo;re a long way from making any decisions.&lt;/p&gt;&#xA;&lt;p&gt;The game will be on Steam and GOG for Mac, Windows and Linux.  It will also be on Switch, Xbox and PlayStation.&lt;/p&gt;&#xA;&lt;p&gt;iOS and Android are hard because premium (paid) games don&amp;rsquo;t do well unless we can get into Apple Arcade or Google Play Pass and being included in those is largely not up to us.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;re not doing a Kickstarter as the game is already funded, but we would like to figure out ways to do fun things like the phonebook and other goodies.&lt;/p&gt;&#xA;&lt;p&gt;Please don&amp;rsquo;t suggest we put it on retro platforms because while the game is pixel art it uses shaders, FMOD and other modern tech.&lt;/p&gt;&#xA;&lt;p&gt;It will be translated into EFIGS and a few other languages. Only English is planned for voice recording.&lt;/p&gt;&#xA;&lt;p&gt;Not happy with the colors on the dev blog, open to suggestions, but I&amp;rsquo;m stubborn.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ndash; Ron&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
