<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <atom:link href="https://freeston.me/feed.xml" rel="self" type="application/rss+xml"/>
    <title>freeston.me</title>
    <link>https://freeston.me/</link>
    <description>Another tech blog, probably</description>
    <lastBuildDate>Wed, 29 Nov 2023 09:16:21 +0000</lastBuildDate>
    <item>
      <pubDate>Wed, 29 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2023-11-29-a-year-as-a-clojure-developer</guid>
      <link>https://freeston.me/posts/2023-11-29-a-year-as-a-clojure-developer</link>
      <title>A Year as a Professional Clojure Developer</title>
      <description><![CDATA[<p>Yesterday marked the end of my first year in my current role, where I joined as a "full stack" developer in a company that primarily uses Clojure having worked almost exclusively as an iOS developer using Objective-C and Swift and using Clojure in my spare time.</p><p>Not only that, but as of earlier this year I'm also a founding member of our Cloud Platform team, which well and truly completes my move away from being a mobile developer. I'm incredibly grateful to my current employer for giving me a chance even though my professional experience wasn't an obvious match. Sixteen months ago I doubted I'd ever be able to make this leap and now I spend my days writing Clojure tooling, libraries and services and spinning cloud infrastructure up and down with terraform. I'm learning so much every day, and most weeks I genuinely look forward to going to work.</p><p>There's nothing more to this post than that. I just wanted a record of this for myself, and just maybe it'll inspire someone else some day: I took a (small) leap by applying to the kind of job I wanted rather than what I'd been doing, someone was willing to tkae a chance on me, and now I'm happier with my work than I've been in a very long time. Sometimes you've just got to take a moment to  appreciate what you've achieved and what you've got.</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 10 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2023-06-10-thoughts-on-dragonruby</guid>
      <link>https://freeston.me/posts/2023-06-10-thoughts-on-dragonruby</link>
      <title>Thoughts on DragonRuby (from a Clojure convert)</title>
      <description><![CDATA[<p><img src="/img/dragonruby/animatch-penguin.png"></p><p>Clojure is my favourite language at this point; I've been using it to make art and websites for a few years, and last year got my first job using it. I was all in and I'd never have to write in a lesser language again. And then I spent most of my spare time this year writing <a href='https://animatch.freeston.me/'>small</a> <a href='https://dominicfreeston.itch.io/hey-thats-my-yarn'>games</a> in <a href='https://github.com/dominicfreeston/kifass2023'>Ruby</a>. What gives?</p><p>The reason is I wanted to make games again, and the reason is the <a href='https://dragonruby.itch.io/dragonruby-gtk'>DragonRuby Game Toolkit (DR)</a>. Many people come to DR because of Ruby, but I'm using it despite it using Ruby, so I thought I'd write down some things I think it has going for it that's not "you can write your game in Ruby".</p><h2>It's a 2D-first code-only engine</h2><p>For some it's a limitation, for me it's a strength. I made The Wallslider in Godot and I think it's an amazing open source project (Godot, not my game); but it does a lot of things I just don't need and they're always <i>there</i> in the editor. I have no interest in making 3D games. DragonRuby's focus on 2D means its APIs are designed and optimised for my use case, and I get to keep working in my beloved Emacs.</p><h2>Simple, low-level, data-oriented APIs</h2><p>The creator of DR, Amir Rajan, has said this aspect of DR's design is inspired by Clojure which might explain why despite the languages' many differences I feel quite at home in this strange corner of Ruby-land (all the mutation still makes me feel icky though).</p><p>There's no complex machinery or class hierarchy to hook into - just some simple basic abstractions to build on top of as you see fit.</p><p>There's a <code>tick</code> function (method, technically, but we can pretend), that gets called 60 times a second (or as close as it can get), and each tick you tell DR what to render, handle input, compute any changes to your game state, etc.</p><p>Rendering graphics and playing audio is just pushing hashes (maps/dictionaries) into arrays and letting the engine handle the rest. Handling input is just checking the current state.</p><p>That's about it. The rest is up to you. But actually there's lots of well considered helper functions for collision detection, easing and interpolation, animation, etc and dozens and dozens of examples provided for all kinds of game styles and features.</p><h2>Dogmatic dedication to cross-platform support and easy deployment.</h2><p>This is one of the main reasons I'm investing time in DR - Amir created DR to solve his own problems as a solo indie game developer trying to ship multiple games on multiple platforms.</p><p>As someone's who's built mobile apps for a living and has seen the effort that can go in supporting even just two platforms, I really appreciate the complete focus on cross platform support.</p><p>This comes with some caveats or limitations, like currently no shaders because doing this truly cross platforms is hard. A lot of these are tied to what <a href='https://en.wikipedia.org/wiki/Simple_DirectMedia_Layer'>SDL</a> supports (one of the <a href='https://en.wikipedia.org/wiki/Ryan_C._Gordon'>developers of DR is also a core contributor and maintainer of SDL</a>), and so some shader support might be on its way with SDL3, but in the meantime it has some features that can fill in a lot of the use cases for shaders in 2D and I can trust that my code will run pretty much identically on all platforms without modification.</p><p>Building for Windows, Mac, Linux and Web with a single command is great - it can even deploy automatically to <a href='https://itch.io/'>itch.io</a> and has beta support for easier <a href='https://store.steampowered.com/'>Steam</a> deployment. I've not yet tried its mobile support and I'm unlikely to ever ship to console, but I like to know they are available with a (quite reasonably priced) pro licence.</p><h2>Hot reload</h2><p>Good hot reload is a super power and DR's is excellent. When I make an error, the built-in console shows me the stack trace and some often helpful error message, then the game picks right back up where it left off with my new changes applied.</p><p>For the situations where your new code can't work with the current state, you can reset the game and you're back in at the start of your game within a second.</p><h2>It's actually pretty fast</h2><p>"But Ruby is slow!" - a language can't be slow, silly! It's down to the implementation. DragonRuby is based on mruby, not the Ruby of Rails, which is designed to be embedded. Also a lot of the engine is actually C, and the developers are even working on a <i>compiler</i> for the Ruby parts. Amir gave a good overview of how the engine works and their future plans at <a href='https://youtu.be/s2rngApV1WU'>rubyconf last year</a>.</p><h2>A lovely supporting community on Discord</h2><p>The docs are somewhat lacking in places, but the <a href='https://discord.dragonruby.org/'>community on discord</a> (which includes the developers themselves) is always there to help and support.</p><h2>The End</h2><p>And that's it. </p><p>It has its quirks (when will DR get circle primitives is a running joke, "just use a sprite" is the official answer) and it lacks the ecosystem of bigger engines, but DragonRuby is pretty darn good and I plan to continue using it for my game making efforts in the foreseeable future (whilst I continue to encourage Amir to make a lisp version).</p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 06 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2022-11-06-the-wallslider-has-left-heroku</guid>
      <link>https://freeston.me/posts/2022-11-06-the-wallslider-has-left-heroku</link>
      <title>The Wallslider has left Heroku</title>
      <description><![CDATA[<p>Like a lot of people recently, I've moved away from Heroku. Not because they're <a href='https://blog.heroku.com/next-chapter'>removing the free tier</a>, but because I was tired of spending $16 a month just to run the leaderboard of <a href='https://thewallslider.com'>my seldom played game</a>.</p><p>The old stack: a <a href='https://clojure.org/'>Clojure</a> app that connects to a <a href='https://www.postgresql.org/'>Postgres</a> database, all hosted on Heroku. It was very easy and allowed me to ship it quickly at the time, but since the game hasn't exactly sold in huge numbers, I was making an ever increasing loss<a href='#fn-1' id='fnref1'><sup>1</sup></a> on keeping the leaderboard running for the handful of people that still play it. </p><p>But I still love my little game and I love those few players! So my main goals were:</p><ol><li>free, or at least no additional costs</li><li>very little extra maintenance burden once the migration was done</li></ol><p>After exploring a few options<a href='#fn-2' id='fnref2'><sup>2</sup></a>, I settled on the cutting edge approach of just using an existing server!</p><p>I'm already running a small VPS on <a href='https://www.digitalocean.com/'>Digital Ocean</a> that serves another Clojure app intended to host various small personal projects. That project's codebase is set up using <a href='https://polylith.gitbook.io/polylith/'>polylith</a>, which lends itself quite well to my needs here. I created a new <a href='https://polylith.gitbook.io/polylith/architecture/2.3.-component'>component</a> for all The Wallslider's server code and then added the few required endpoint to my app's <a href='https://polylith.gitbook.io/polylith/architecture/2.2.-base'>base</a>. That took care of the code.</p><p>While I've gotten much more comfortable with databases the last few years, it doesn't mean I want the hassle of managing a Postgres cluster. But I also don't want to pay someone to manage one for me. </p><p>Enter <a href='https://www.sqlite.org/'>SQLite</a>! As I'm running a single instance of my app on a dedicate (virtual) server, SQLite is more than enough for my needs and the data is now just a file that sits on my server. There was a little bit of SQL tweaking required but it mostly "just worked". The main downside of SQLite is the risk of data loss if something happens to that file or the server it's hosted on.</p><p>Enter <a href='https://litestream.io/'>Litestream</a>! This is designed exactly for my kind of scenario, small to medium apps that want to safeguard their data but keep the simplicity of using SQLite. It does so by streaming changes to an S3 compatible bucket, which is generally pretty cheap. But better than cheap is free.</p><p>Enter <a href='https://www.cloudflare.com/products/r2/'>Cloudflare R2</a>! They have a generous free tier which is more than enough for my tiny app and its tiny database.</p><p>Now I have all the tools I need and a new stack: A Digitial Ocean droplet running my Clojure app (fronted by nginx, which redirects various domains to the right endpoints), SQLite and Litestream and an R2 bucket to safeguard the data.</p><p>The total cost is about 7$/month for the droplet, which I was already spending and can continue adding other small projects to it. If any project ever takes off and needs to scale, polylith should make it straightforward to package the right components into a different app and ship it separately. Overall I'm pretty happy with this new setup.</p><ol class='footnotes'><li id='fn-1'>I'm still spending money on the domain and my Apple developer account. The latter is a fixed cost no matter how many apps I have, but currently The Wallslider is the only app I have, and I'm considering releasing a new version that points to app.freeston.me instead so I can eventually drop the domain altogether.<a href='#fnref1'>&#8617;</a></li><li id='fn-2'>Including <a href='https://fly.io'>fly.io</a>, which seems very cool and employs <a href='https://twitter.com/benbjohnson'>Ben Johnson</a> who created Litestream.<a href='#fnref2'>&#8617;</a></li></ol>]]></description>
    </item>
    <item>
      <pubDate>Wed, 15 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2022-06-15-html-form-download</guid>
      <link>https://freeston.me/posts/2022-06-15-html-form-download</link>
      <title>Triggering a download from an HTML form (using hyperscript)</title>
      <description><![CDATA[ <h2><em>Before you head down the rabbit hole</em></h2><p>The approach described here is entirely unnecessary if you control the API: add the <a href='https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition'><code>Content-Disposition: attachment</code> header</a> to the response and the browser should download the file rather than display it.  </p><h2>The Problem</h2><p>I want the user of a web page to be able select some parameters, then click a button that triggers the download of a document (in my case an SVG file) based on those selected parameters. The API being used is designed as a GET request with query parameters - this last bit is important for the approach described here to be viable.</p><p>A <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form'><code>&lt;form&gt;</code></a> is a nearly-perfect HTML-only solution, except that the <a href='https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/download'><code>download</code></a> property is only available on anchor (<code>&lt;a&gt;</code>) elements. The best I can do is set the <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-target'><code>target</code> attribute to <code>&#95;blank</code></a> and have it open in a new tab or window.</p><p>It looks simply like this:<pre><code class="html">&lt;form action=&quot;some-url&quot; method=&quot;get&quot; target=&quot;&#95;blank&quot;&gt;
  ... form content ...
  &lt;button &quot;type=&quot;submit&quot;&gt;Download&lt;/button&gt;
&lt;/form&gt;
</code></pre></p><h2>The Approach</h2><p>I decided to use scripting to replace the <code>&lt;button&gt;</code> with an <code>&lt;a&gt;</code> tag that points to the same URL the form would and keep that URL up to date whenever the content of the form changes.</p><p>For this I decided to use <a href='https://hyperscript.org/'>hyperscript</a><a href='#fn-1' id='fnref1'><sup>1</sup></a>. Firstly, I defined a function to build up the equivalent GET url for a form and put it in a <a href='https://hyperscript.org/docs/#install'><code>&lt;script&gt;</code> tag</a>:</p><pre><code class="text hljs">def formURL&#40;form&#41;
  set vs to form as Values
  set params to Object.keys&#40;vs&#41;.map&#40; \ k -&gt; k + '=' + vs&#91;k&#93;&#41;.join&#40;'&amp;'&#41;
  return &#40;@action of form&#41; + '?' + params
end
</code></pre><p>Then when the page loads, I replace the button with an anchor using the following script on the submit button:</p><pre><code class="text hljs">init make &lt;a#download-link/&gt;
put '&lt;filename&gt;' into its @download
put formURL&#40;closest &lt;form/&gt;&#41; into its @href
put my.innerHTML into it
put it after me
remove me
</code></pre><p>It's a bit wordy, but should be fairly self-explanatory (hyperscript is good like that). The reason I do this part with a script rather than simply use an anchor to begin with is to embrace the idea of <a href='https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement'>progressive enhancement</a>. If JavaScript is disabled or the HyperScript dependency can't be loaded, we're still left with our default working behaviour of opening the file into a new tab.</p><p>With a bit of CSS I can make the button and the anchor look the same, making the experience virtually identical in both scenarios (apart from the download enhancement) and avoid any visible flash as one element replaces the other.</p><p>Finally, the key part is to keep the URL up to date as the form's inputs change, which can now be done by attaching this one-liner to the form element<a href='#fn-2' id='fnref2'><sup>2</sup></a>:</p><pre><code class="text hljs">on change put formURL&#40;me&#41; into @href of #download-link
</code></pre><h2>The Result</h2><p>The resulting code is sufficiently generic that it should be possible to drop this into any HTML page and have it mostly "just work"<a href='#fn-3' id='fnref3'><sup>3</sup></a>:</p><pre><code class="html">&lt;script src=&quot;https://unpkg.com/hyperscript.org@0.9.5&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/hyperscript&quot;&gt;
  def formURL&#40;form&#41;
    set vs to form as Values
    set params to Object.keys&#40;vs&#41;.map&#40; \ k -&gt; k + '=' + vs&#91;k&#93;&#41;.join&#40;'&amp;'&#41;
    return &#40;@action of form&#41; + '?' + params
  end
&lt;/script&gt;

&lt;form action=&quot;some-url&quot; method=&quot;get&quot; target=&quot;&#95;blank&quot;
      &#95;=&quot;on change put formURL&#40;me&#41; into @href of #download-link&quot;&gt;

  ... form content ...
  
  &lt;button type=&quot;submit&quot;
          &#95;= &quot;init make &lt;a#download-link/&gt;
              put '&lt;filename&gt;' into its @download
              put formURL&#40;closest &lt;form/&gt;&#41; into its @href
              put my.innerHTML into it
              put it after me
              remove me&quot;&gt;
    Download
  &lt;/button&gt;
&lt;/form&gt;
</code></pre><ol class='footnotes'><li id='fn-1'>For no other reason than I've been meaning to give it and its companion <a href='https://htmx.org/'>htmx</a> a go, though it does seem particularly well suited to this kind of DOM manipulation.<a href='#fnref1'>&#8617;</a></li><li id='fn-2'>At first I thought I needed to attach this script to every field in the form, but putting it on the form element itself seems to do the trick.<a href='#fnref2'>&#8617;</a></li><li id='fn-3'>Of course, the filename will need to be updated to something suitable and the form content needs to be filled in!<a href='#fnref3'>&#8617;</a></li></ol>]]></description>
    </item>
    <item>
      <pubDate>Thu, 12 May 2022 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2022-05-12-a-minimal-html-reload-workflow</guid>
      <link>https://freeston.me/posts/2022-05-12-a-minimal-html-reload-workflow</link>
      <title>A minimal HTML reload workflow</title>
      <description><![CDATA[<p>I've been brushing up on <a href='https://every-layout.dev/'>modern css layouts</a> and I wanted something that would reload my changes automatically. Since I'm on Ubuntu with X11, I can use <a href='https://manpages.ubuntu.com/manpages/focal/man1/xdotool.1.html'>xdotool</a> to send keyboard commands to my browser.</p><p>I was working with a <a href='https://babashka.org/'>babashka</a> file which spits out an HTML file when I evaluate it and since babashka can also easily run shell commands,  I figured I could just add these two lines at the bottom of my <a href='https://book.babashka.org/#_nrepl'>nrepl-connected script</a>:</p><pre><code class="clojure">&#40;defonce browser-window
  &#40;:out &#40;shell/sh &quot;xdotool&quot; &quot;selectwindow&quot;&#41;&#41;&#41;
&#40;shell/sh &quot;xdotool&quot; &quot;key&quot; &quot;--window&quot; browser-window &quot;F5&quot;&#41;
</code></pre><p>The first time it's evaluated, I can use the mouse to select the desired window and from then on that window will be reloaded every time I evaluate the file. There's a bit of a limitation in that it doesn't care what the current browser tab is, it just triggers whatever is currently selected, but it's good enough for my purposes.</p><p>Job done! Well, not quite.</p><p>Of course this doesn't automate the reload when tweaking the CSS file. And it would be nice to have that functionality when working on this site. Really, I need a file watcher, and happily there's a <a href='https://github.com/babashka/pods'>babashka pod</a> <a href='https://github.com/babashka/pod-babashka-fswatcher'>for file watching</a><a href='#fn-1' id='fnref1'><sup>1</sup></a>. Hooking it up is straightforward, but when there's dozens or even hundreds of file changes, it gets a bit manic, so I hacked up together a debouncer using a cancellable future in an atom <a href='#fn-2' id='fnref2'><sup>2</sup></a>:</p><pre><code class="clojure">&#40;def reload-op &#40;atom nil&#41;&#41;
&#40;defn trigger-reload &#91;&#93;
  &#40;let &#91;&#91;old &#95;&#93; &#40;reset-vals! reload-op &#40;future &#40;Thread/sleep 20&#41; &#40;reload&#41;&#41;&#41;&#93;
    &#40;when old &#40;future-cancel old&#41;&#41;&#41;&#41;

</code></pre><p>I also used the same mechanism to implement a <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/src/freeston/watch.clj'><code>watch</code></a> command for this site which triggers a re-render whenever a file changes. Combined with the browser reload script watching the output folder, it makes for a nice workflow.</p><p>The full script is <a href='https://gist.github.com/dominicfreeston/76d4adc6b3594a345f8d2cf683c51a88'>available as a gist</a> and requires babashka and xdotool to be installed. I ended up also making a <a href='https://gist.github.com/dominicfreeston/b2b58236752b419fd19cd7d982e114bb'>macOS version</a> that makes use of AppleScript to trigger the reload instead. If you're reading this, I hope you find it useful.</p><ol class='footnotes'><li id='fn-1'>Well, there's <a href='https://github.com/babashka/pod-babashka-filewatcher'>two</a>.<a href='#fnref1'>&#8617;</a></li><li id='fn-2'>I got some advice on how to improve it from the <a href='https://clojurians.slack.com/'>clojurians slack</a>, some of which I even applied, though I can't apply it all now because of a current <a href='https://github.com/babashka/babashka/issues/1264'>limitation in babashka</a>. I did learn about <a href='https://clojuredocs.org/clojure.core/reset-vals!'><code>reset-vals!</code></a> which is better than accessing the atom to cancel it and then calling <code>reset!</code>. Some also suggested an approach using core.async which sounds cool but maybe overkill for this particular hack.<a href='#fnref2'>&#8617;</a></li></ol>]]></description>
    </item>
    <item>
      <pubDate>Mon, 29 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-11-29-new-site-generator</guid>
      <link>https://freeston.me/posts/2021-11-29-new-site-generator</link>
      <title>I wrote myself a static site generator</title>
      <description><![CDATA[<h2>The Story</h2><p>I replaced a <a href='http://cryogenweb.org/'>perfectly fine static-site generator</a> with a custom one. I had been wanting to make some modifications to my site and whilst it was <a href='http://cryogenweb.org/docs/customizing-cryogen.html'>absolutely possible</a> to do so previously, I never felt particularly inclined to do it. I don't love writing HTML, even less so writing <a href='https://github.com/yogthos/Selmer'>django-style templates</a>. I much prefer working with something like <a href='https://github.com/weavejester/hiccup'>hiccup</a>. I guess I'm easily influenced because a <a href='https://blog.hamaluik.ca/posts/build-your-own-static-site-generator/'>blog post by an author I've never come across before</a> planted the seed.</p><p>I was always going to stick with Clojure and had been intending to look into <a href='https://babashka.org/'>Babashka</a>, a subset of Clojure with precompiled built-in libraries intended for scripting. I recently saw that <a href='https://twitter.com/borkdude'>Michiel Borkent</a>, the author of Babashka, had used it to <a href='https://blog.michielborkent.nl/migrating-octopress-to-babashka.html'>replace his previous Octopress blog</a>. I thought I'd see if I could do something similar, keeping open the option of switching back to Clojure if things didn't work out.</p><p>Babashka comes with a bunch of useful libraries built-in, but it doesn't include any markdown parsing. It does provide a mechanism for other utilities to expose their functionality as Clojure namespaces. I initially attempted to use one called <a href='https://github.com/retrogradeorbit/bootleg'>bootleg</a>. Whilst it uses the same <a href='https://github.com/yogthos/markdown-clj'>markdown parser</a> my site was using, it didn't expose the footnotes option that my existing posts rely on. I <a href='https://github.com/retrogradeorbit/bootleg/pull/76'>opened a PR addressing the issue</a>, but the library isn't actively maintained and I'm still not sure if or when I'll get a reply <a href='#fn-1' id='fnref1'><sup>1</sup></a>. </p><p>Raising the issue, however, prompted <a href='https://blog.michielborkent.nl/markdown-clj-babashka-compatible.html'>Michiel to wonder whether Babashka could run markdown-clj directly from source</a>. Amazingly, although there were a couple of minor issues stopping it from working initially, within less than day he had fixed the issues, got them merged in upstream and had written all about it! I now had all the tools I needed to recreate my site.</p><h2>The Outcome</h2><p>At the time of writing, the code for the site now consists of:</p><ul><li>~170 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/src/freeston/core.clj'>parsing and rendering code</a></li><li>~170 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/src/freeston/templates.clj'>hiccup templates</a></li><li>~50 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/src/freeston/feed.clj'>RSS feed template</a></li><li>~70 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/src/freeston/server.clj'>local development server to preview the site</a></li><li>~20 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/bb.edn'>babashka project and tasks definitions</a></li><li>4 lines <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/main/build.sh'>bash script to get Netlify to install babashka and build the site</a></li></ul><p>I replicated the layout and design of my site almost exactly. I kept the same <a href='https://github.com/dominicfreeston/freeston-dot-me/tree/main/static/css'>CSS files</a> and the hiccup templates are equivalent to the <a href='https://github.com/dominicfreeston/freeston-dot-me/tree/545b6da58c3f21cca3b9d44b638e6d2392763c04/themes/freeston/html'>original ones</a>. I used my new found custom-code-freedom to make a <a href='https://github.com/dominicfreeston/freeston-dot-me/blob/083b1355995d5be6096af798e6b090b25173e409/src/freeston/templates.clj#L69'>new home page</a>, rather than just display the latest post as it previously did. My intention is to now expand on this and find better ways to share some of my work than just via blog posts.</p><ol class='footnotes'><li id='fn-1'>This isn't a complaint or a criticism - I don't think we're owed anything from free software maintainers, especially so when they're small one-person projects they created to scratch their own itch.<a href='#fnref1'>&#8617;</a></li></ol>]]></description>
    </item>
    <item>
      <pubDate>Mon, 10 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-10-thirty-five-day-35</guid>
      <link>https://freeston.me/posts/2021-05-10-thirty-five-day-35</link>
      <title>Day Thirty-Five of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-10-1927-21-1859519226368439.jpg"></p><p>This is it, the end of my thirty-five day challenge. I <a href='/posts/2021-04-05-thirty-five/'>didn't really know</a> where it would take me, but about <a href='/posts/2021-04-23-thirty-five-day-18/'>halfway through</a> I decided I to aim for a single program that would capture, and ultimately help me explore, some of the ideas and decisions I'd been playing with at the start. Getting a balance between surprise and interest across outputs while maintaining some degree of consistent quality is not something I'd achieved before.</p><p>To put this to the test, I generated 100 images and selected 35 which you can see below - you can click on them to see a larger version. I think it showcases the range but also the consistency of the output. More importantly, by doing this for thirty-five days, I've pushed myself to explore ideas more widely and deeply, and share my process and work in public.</p><p><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2800 2000"> <image width="2800" height="2000" xlink:href="/img/thirty-five/last/all.jpg" /> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-45-1818870960428172.jpg"> 	<rect x="0" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-46-1818871773958303.jpg"> 	<rect x="400" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-48-1818873128902817.jpg"> 	<rect x="800" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-53-1818878643235616.jpg"> 	<rect x="1200" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-55-1818880306448169.jpg"> 	<rect x="1600" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-56-1818881873073282.jpg"> 	<rect x="2000" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2141-59-1818884165448229.jpg"> 	<rect x="2400" y="0" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-01-1818886578346713.jpg"> 	<rect x="0" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-03-1818888073010690.jpg"> 	<rect x="400" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-03-1818888410989688.jpg"> 	<rect x="800" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-15-1818900759849947.jpg"> 	<rect x="1200" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-34-1818919956297833.jpg"> 	<rect x="1600" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-40-1818925894819928.jpg"> 	<rect x="2000" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-41-1818926547052436.jpg"> 	<rect x="2400" y="400" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-45-1818930224703793.jpg"> 	<rect x="0" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-47-1818932330443347.jpg"> 	<rect x="400" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-52-1818937039534685.jpg"> 	<rect x="800" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-56-1818941311620789.jpg"> 	<rect x="1200" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-57-1818942409011254.jpg"> 	<rect x="1600" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2142-59-1818944405563624.jpg"> 	<rect x="2000" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-06-1818951193003301.jpg"> 	<rect x="2400" y="800" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-06-1818951773782950.jpg"> 	<rect x="0" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-22-1818967696639080.jpg"> 	<rect x="400" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-28-1818973294749832.jpg"> 	<rect x="800" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-32-1818977794178115.jpg"> 	<rect x="1200" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-45-1818990192726431.jpg"> 	<rect x="1600" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-48-1818993225251003.jpg"> 	<rect x="2000" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2143-53-1818998928519284.jpg"> 	<rect x="2400" y="1200" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-00-1819005694965030.jpg"> 	<rect x="0" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-02-1819007360752063.jpg"> 	<rect x="400" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-06-1819011311464144.jpg"> 	<rect x="800" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-08-1819013025292324.jpg"> 	<rect x="1200" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-13-1819018293042226.jpg"> 	<rect x="1600" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-14-1819019294816471.jpg"> 	<rect x="2000" y="1600" width="400" height="400" opacity="0" /> </a> <a xlink:href="/img/thirty-five/last/2021-05-09-2144-19-1819024294550208.jpg"> 	<rect x="2400" y="1600" width="400" height="400" opacity="0" /> </a> </svg></p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 09 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-09-thirty-five-day-34</guid>
      <link>https://freeston.me/posts/2021-05-09-thirty-five-day-34</link>
      <title>Day Thirty-Four of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-09-1901-07-1813197082340049.jpg"></p><p>As planned, I added a few restrictions to the code so that a few particular combinations of parameters that consistently lead to bad outputs now simply can't happen. With one more day to go to complete my challenge, the process is very much one of curation, but unlike <a href='/posts/2021-04-30-thirty-five-day-25/'>nine days ago</a>, the number of interesting outputs is much higher and and I'm able to refine them a bit if required (though I haven't felt the need to do so for a few days now).</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 08 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-08-thirty-five-day-33</guid>
      <link>https://freeston.me/posts/2021-05-08-thirty-five-day-33</link>
      <title>Day Thirty-Three of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-08-0916-52-1799505283273307.jpg"></p><p>I've refined, biased and restricted the colour code so that it mostly generates a pleasing colour scheme with a somewhat consistent style, whilst also keeping a good degree of variation.</p><p>I've started to identify combinations of features that tend to lead disappointing results and I'm hoping to spend some time tomorrow putting a few more restrictions to stop these from happening. I'm actually fairly hopeful that I might end the challenge on Monday with a program that somewhat reliably outputs interesting results.</p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 07 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-07-thirty-five-day-32</guid>
      <link>https://freeston.me/posts/2021-05-07-thirty-five-day-32</link>
      <title>Day Thirty-Two of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-07-2223-05-1705441436164516.jpg"></p><p>I've been exploring the kind of colour palettes I can generate dynamically using <a href='https://iquilezles.org/www/articles/palettes/palettes.htm'>a technique</a> I came across yesterday. Although it's still difficult to get varied but consistently attractive palettes, it is indeed a good way to get exposed to a wide range of options. I can select either a colour palette or the composition that I like and then continue exploring possibilities from there. Today's piece however, came out of the code fully formed.</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 06 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-06-thirty-five-day-31</guid>
      <link>https://freeston.me/posts/2021-05-06-thirty-five-day-31</link>
      <title>Day Thirty-One of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-06-1950-14-1702194466006941.jpg"></p><p>I did a couple of minor tweaks (multiple colours within the large shapes and drawing them over the rest rather than behind) and I coerced some of the parameters to refine the output, but otherwise it's the same program as the last few days. Overall, I'm happy with the variety I'm getting out of this code and I feel I have mostly achieved what I set out to do when <a href='/posts/2021-04-23-thirty-five-day-18/'>I re-evaluated my goal halfway through the project</a>. The quality of the output isn't as  consistent as I thought I'd get to, but in return I get more variety and surprises.</p><p>This is going to be the last piece in the series with the bubblegum colour palette, though I am still loving it! With four days to go, I've decided to revisit my conclusion that <a href='/posts/2021-05-03-thirty-five-day-28/'>generating a colour palette isn't realistic</a>. I've <a href='https://observablehq.com/@makio135/give-me-colors'>come across</a> <a href='https://iquilezles.org/www/articles/palettes/palettes.htm'>a promising technique</a> that seems to allow for the creation of consistently workable palettes. At the very least it may be a good tool for discovery.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 05 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-05-thirty-five-day-30</guid>
      <link>https://freeston.me/posts/2021-05-05-thirty-five-day-30</link>
      <title>Day Thirty of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-05-1930-25-1658552656768638.jpg"></p><p>I added one small tweak to the algorithm that has opened up new interesting variations and that enabled today's piece. I'm enjoying the bubblegum aesthetic of yesterday and so have kept the colour scheme, adjusting it slightly.</p>]]></description>
    </item>
    <item>
      <pubDate>Tue, 04 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-04-thirty-five-day-29</guid>
      <link>https://freeston.me/posts/2021-05-04-thirty-five-day-29</link>
      <title>Day Twenty-Nine of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-04-2135-48-1650078160916346.jpg"></p><p>Different day, different colours. This is a colour palette I actually stumbled upon yesterday when trying to find a generic way of creating a pleasing palette - probably not one I would have initially aimed for but it has caught my attention.</p>]]></description>
    </item>
    <item>
      <pubDate>Mon, 03 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-03-thirty-five-day-28</guid>
      <link>https://freeston.me/posts/2021-05-03-thirty-five-day-28</link>
      <title>Day Twenty-Eight of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-03-1026-03-1600437117364912.jpg"></p><p>It's not exactly a newfound revelation that using colour well is difficult, <a href='https://tylerxhobbs.com/essays/2021/color-arrangement-in-generative-art'>perhaps even more so in generative works</a>. I've been playing around with alternative colour spaces in the hope, perhaps rather naively, of being able to find operations that consistently generate great combinations from a base randomly selected colour. It hasn't been going particularly well! Today's colours were the outcome of manual trial and error.</p><p>Whilst a little bit of randomness for small colour variations can add texture and depth and the exact location of each colour can be left to the whims of the algorithm, I think I'm ready to accept that selecting the colour palette of a piece is something I'll need to do the old fashion way and continue working at.</p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 02 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-02-thirty-five-day-27</guid>
      <link>https://freeston.me/posts/2021-05-02-thirty-five-day-27</link>
      <title>Day Twenty-Seven of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-02-1911-25-1588633221520853.jpg"></p><p>I spent today trying out different ways of picking colours programatically, with mixed results. The piece I chose today has a nice tone but also the composition turned out better than most.</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 01 May 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-05-01-thirty-five-day-26</guid>
      <link>https://freeston.me/posts/2021-05-01-thirty-five-day-26</link>
      <title>Day Twenty-Six of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-05-01-2309-51-1571437766583106.jpg"></p><p>After generating a few drawings, I picked the most interesting one and tweaked the code to refine one of the aspects of the piece - namely, the circles at the top of the piece are now of varied size and warped to not be perfect circle, giving it a more organic and balanced feel.</p><p>Depending on the structure of the program, refining a particular aspect of a piece can be tricky as there are so many random elements. Changing in which order those random decisions are made can completely change the piece. Over the last couple of days I've purposefully rearranged the code so that decisions that affect the overall composition happen before decisions that affect the details, making it more likely I can target just the part of the program I want to modify without completely altering the result.</p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-30-thirty-five-day-25</guid>
      <link>https://freeston.me/posts/2021-04-30-thirty-five-day-25</link>
      <title>Day Twenty-Five of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-30-2057-28-1558219936465405.jpg"></p><p>My process today has consisted mostly of generating a bunch of pieces and choosing my favourite - one that feels more like curation than creation at this point. Whilst the range of outputs is now quite varied, it's also incredibly inconsistent and difficult to refine when something interesting pops up. I think it's a constant tension with generative art.</p><p>I see a couple of directions to take for the remaining 10 days this project. Now that I can capture some of the high level parameters that led to a particular drawing, I could either try and figure out what combinations tend to lead to better outcomes and make these more likely, or I could use it as a way to freeze a particular combination to then refine until I'm satisfied.</p><p>Of course another possibility is to try and incorporate colour again, which feels rather daunting when there's already so many variables. Let' see where tomorrow takes me.</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 29 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-29-thirty-five-day-24</guid>
      <link>https://freeston.me/posts/2021-04-29-thirty-five-day-24</link>
      <title>Day Twenty-Four of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-29-2205-26-1516861293294621.jpg"></p><p>Today's output is from essentially unchanged code - at least none of the possible outcomes have changed, no new feature and no tweaking of the parameters.</p><p>What I have started to do is centralise some of they key decision points into a structure that I then use throughout the code. This will help me make sense of which properties are the most impactful and what combinations of parameters create the most interesting outputs.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 28 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-28-thirty-five-day-23</guid>
      <link>https://freeston.me/posts/2021-04-28-thirty-five-day-23</link>
      <title>Day Twenty-Three of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-28-2201-39-1479453844424268.jpg"></p><p>Today, some minor refinements to the code, this time to expand the range of possible values and combinations.</p>]]></description>
    </item>
    <item>
      <pubDate>Tue, 27 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-27-thirty-five-day-22</guid>
      <link>https://freeston.me/posts/2021-04-27-thirty-five-day-22</link>
      <title>Day Twenty-Two of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-27-2301-23-1454880351955433.jpg"></p><p>Today brings in another of the main elements used during the first half of the project - the horizontal wavy lines. Depending on how they are cropped, to the inside or outside of the various shapes, they play a very different part in the composition. Their addition opens up the range of possible outputs, and with it the potential for surprise, even more.</p>]]></description>
    </item>
    <item>
      <pubDate>Mon, 26 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-26-thirty-five-day-21</guid>
      <link>https://freeston.me/posts/2021-04-26-thirty-five-day-21</link>
      <title>Day Twenty-One of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-26-2153-01-1405889343303256.jpg"></p><p>Some minor tweaks to the code today, trying to reign in the possibilities just a bit to get a higher proportion of results I like. The output I chose is much more minimal than most in this series but has a lovely feel to it and fits nicely with the type of plotter art I generally like to make. I feel like I'm at another crossroad between looking to bring in more colours and layered textures, or continue expanding on the possibilities within the constraint of line drawings.</p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 25 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-25-thirty-five-day-20</guid>
      <link>https://freeston.me/posts/2021-04-25-thirty-five-day-20</link>
      <title>Day Twenty of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-25-2253-03-1361274494577601.jpg"></p><p>I spent some time <a href='https://github.com/ptaoussanis/tufte'>profiling</a> and optimising my code again today, with some really great improvements, making continued development much smoother.</p><p>I brought in another key feature used throughout the series - the flow lines. There's multiple ways the starting points are selected and the length can vary quite a lot. I've also added the possibility of sub-dividing the small circles into groups so that they are treated differently.</p><p>I'm already getting a lot of interesting variation in the output, which is making it harder to choose one for the day - a nice problem to have. I've selected this one in part because it showcases some of the new possible features.</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 24 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-24-thirty-five-day-19</guid>
      <link>https://freeston.me/posts/2021-04-24-thirty-five-day-19</link>
      <title>Day Nineteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-24-2153-45-1328325883238038.jpg"></p><p>Today I gave the code the option of warping the circles and/or replacing the circle with parallel lines. The large and small circles are treated separately, with the inclusion of the large circles being randomised. I'm already getting quite a bit of variation - some good, some bad, some surprising. My choice for today neatly showcases some of the new possibilities.</p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 23 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-23-thirty-five-day-18</guid>
      <link>https://freeston.me/posts/2021-04-23-thirty-five-day-18</link>
      <title>Day Eighteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-23-2258-28-1306020262383306.jpg"></p><p>The last few days have been a struggle, and as I pass the halfway point it is time for some reflection. I've shown to myself that I can produce something every day. I've been able to both refine an idea and take leaps to explore alternatives, and have found that the most interesting result don't always come when I'm feeling inspired. And crucially I've posted something online each day, even on days I've been disappointed with my efforts.</p><p>One thing I've been missing is that I'm rarely surprised by the output of my code - I've been trying to coerce something "good" out of it every day, reducing the variance too much. Part of the reason for this is that pure randomness is easy to implement, but the output rarely pleasing or interesting to look at, particularly when it comes to the overall composition of piece (it can still be quite useful for detail and texture).</p><p>I've decided to take the "same evolving codebase" of my original plan more literally. I've looked back at what I've created so far and I want to increase the variance between each run of the program, but bake in some of the kinds of decisions I've been making.</p><p>Today I went back to basics and started with placing circles, which all the pieces have relied on in some way. There's between 1 and 4 large circles, which can then influence the placement of the smaller circles (or not). The smaller circles themselves can be spread evenly or layered as first introduced in day four. For today's piece I then decided to only draw the small circles, using the large one as negative space.</p><p>I plan to build on this for the rest of the challenge, incorporating some elements from the first half as possibilities for the program to select. My hope is that by the end I have a single program that generates a variety of  consistently pleasing and/or interesting outputs.</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 22 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-22-thirty-five-day-17</guid>
      <link>https://freeston.me/posts/2021-04-22-thirty-five-day-17</link>
      <title>Day Seventeen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-22-2121-05-1225570564096277.jpg"></p><p>I got today's output within 15 minutes of starting then spent over an hour trying different variations, only to return to this one. Even though it is using essentially the same background as yesterday's, it has a very different feel.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 21 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-21-thirty-five-day-16</guid>
      <link>https://freeston.me/posts/2021-04-21-thirty-five-day-16</link>
      <title>Day Sixteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-21-2156-58-1181457414119842.jpg"></p><p>I took the perpendicular lines from yesterday's and did something a bit different with them, looking for a more flowing feel. The key change at the end was to dramatically increase the number of lines and reduce the opacity - a trick which I find can be quite effective at generating pleasing textures<a href='#fn-1' id='fnref1'><sup>1</sup></a>, but for some reason often feels like cheating. I think it's because a lot of my work is intended to be plotted, limiting me mostly to solid lines<a href='#fn-2' id='fnref2'><sup>2</sup></a>, a restriction I'm not bound to for this project.</p><ol class='footnotes'><li id='fn-1'>The background uses a similar technique, as so do many of the previous pieces in the series.<a href='#fnref1'>&#8617;</a></li><li id='fn-2'>Though depending on the pen used, some interesting layering effects can be achieved.<a href='#fnref2'>&#8617;</a></li></ol>]]></description>
    </item>
    <item>
      <pubDate>Tue, 20 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-20-thirty-five-day-15</guid>
      <link>https://freeston.me/posts/2021-04-20-thirty-five-day-15</link>
      <title>Day Fifteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-20-2227-06-1160051558553725.jpg"></p><p>I started playing with the colours of yesterday's piece, and although I liked some of the results, it didn't feel like much of a step forward, so I tried to play with the composition of the piece. I don't think I really know how I feel about it yet, but it should offer me a different avenue for exploration tomorrow.</p>]]></description>
    </item>
    <item>
      <pubDate>Mon, 19 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-19-thirty-five-day-14</guid>
      <link>https://freeston.me/posts/2021-04-19-thirty-five-day-14</link>
      <title>Day Fourteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-19-2159-08-1082971848003258.jpg"></p><p>I started off tonight feeling completely uninspired and aimless - without the challenge in place I would have not produced anything today. And yet I've managed to create what might be my favourite of the series so far. Once again I've reused many of the elements from previous pieces but reworked and combined them in different ways. Many of the previous days have evoked the physical world - clouds, flowers, stars, planets - but to me today's piece doesn't do any of that, it stands on its own.</p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 18 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-18-thirty-five-day-13</guid>
      <link>https://freeston.me/posts/2021-04-18-thirty-five-day-13</link>
      <title>Day Thirteen of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-18-2136-43-1001188309041625.jpg"></p><p>Today is a refinement of yesterday's piece, improving the composition (but still without fully specifying the various elements' location) and changing the background colors.</p><p>I haven't generally worried about the performance of my code as I produce mostly static images, but I've been getting frustrated by just how long it can take to render some drawings. I went digging into <a href='https://github.com/dominicfreeston/penny'>my library</a>'s circle packing code, which I've been making heavy use of. I found some rather naive things I'd done that I've started to optimise, with some already significant improvements. I just need to resist the temptation to spend too long tinkering and focus on the art!</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 17 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-17-thirty-five-day-12</guid>
      <link>https://freeston.me/posts/2021-04-17-thirty-five-day-12</link>
      <title>Day Twelve of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-17-2316-34-946637501750118.jpg"></p><p>I combined most aspects of <a href='/posts/2021-04-13-thirty-five-day-8/'>day eight</a> with the patterns of days <a href='/posts/2021-04-14-thirty-five-day-9/'>nine</a> and <a href='/posts/2021-04-15-thirty-five-day-10/'>ten</a> to create something that feels a bit like outer space (which kind of fits with yesterday's rushed effort). I also tried to add a few more colours, which is not something I'm yet comfortable with - most of my previous work has been in black and white.</p><p>In previous days I applied a lot of constraints to the placement of the main elements, going as far as just specifying their location. Today I decided to leave it to randomness (within the constraints of the circle packing algorithm) and it's been quite frustrating. So far I've found that manually specifying the overall composition whilst using randomness for the detail to be the most successful approach, with the caveat that any particular result is very rarely surprising.</p><p>This daily challenge is really putting my <a href='/posts/2021-03-27-quil-workflow/'>latest workflow</a> to the test and I'm rather happy with it. I'm able to freely modify my code without fear of losing track of a good idea and can easily revisit previous versions and pull out specific aspects I want to incorporate.</p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 16 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-16-thirty-five-day-11</guid>
      <link>https://freeston.me/posts/2021-04-16-thirty-five-day-11</link>
      <title>Day Eleven of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-16-2321-35-890988377708586.jpg"></p><p>Life gets in the way! I spent this evening playing <a href='https://www.mothershiprpg.com/'>Mothership</a>, a horror-in-space tabletop RPG that involved spooky floating hair and emergency lighting, so I hacked at my code whilst playing and tried to channel that. Not my most thought-through piece, but something a bit different again using similar techniques.</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 15 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-15-thirty-five-day-10</guid>
      <link>https://freeston.me/posts/2021-04-15-thirty-five-day-10</link>
      <title>Day Ten of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-15-2229-24-837070214172721.jpg"></p><p>Not a lot of time today, but combining aspects of <a href='/posts/2021-04-14-thirty-five-day-9/'>day 9</a> and <a href='/posts/2021-04-12-thirty-five-day-7/'>day 7</a> to get something out - <a href='/posts/2021-04-05-thirty-five/'>this challenge</a> is all about that consistency of output and removing the fear of sharing my work. So here's to double digits, and another 25 days.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 14 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-14-thirty-five-day-9</guid>
      <link>https://freeston.me/posts/2021-04-14-thirty-five-day-9</link>
      <title>Day Nine of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-14-2119-21-786757392035610.jpg"></p><p>A bit of a reset today, starting with a different way of utilising a flow field by warping a series of horizontal lines along the y axis. A few of the pieces in this challenge have evoked the sky and I leaned into this theme with the circle crop when the colour gradient reminded me of a setting sun.</p>]]></description>
    </item>
    <item>
      <pubDate>Tue, 13 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-13-thirty-five-day-8</guid>
      <link>https://freeston.me/posts/2021-04-13-thirty-five-day-8</link>
      <title>Day Eight of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-13-2206-44-776763299073732.jpg"></p><p>This is actually very similar code to yesterday's piece, exactly the same structure but with some different values for a variety of parameters. Even though I'm not entirely happy with today's piece, this is one of the things I love about generative art - how quickly you can explore quite a wide possibility space.</p>]]></description>
    </item>
    <item>
      <pubDate>Mon, 12 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-12-thirty-five-day-7</guid>
      <link>https://freeston.me/posts/2021-04-12-thirty-five-day-7</link>
      <title>Day Seven of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-12-2121-28-729659166629970.jpg"></p><p>Today's is a refinement of <a href='/posts/2021-04-10-thirty-five-day-5/'>day 5</a>, focusing on the light and texture of the background.</p>]]></description>
    </item>
    <item>
      <pubDate>Sun, 11 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-11-thirty-five-day-6</guid>
      <link>https://freeston.me/posts/2021-04-11-thirty-five-day-6</link>
      <title>Day Six of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-11-2147-45-682842743310312.jpg"></p><p>Some further exploration of the blossoms vibes from yesterday, finding new ways to combine the circle packing, flow fields and layering techniques that all the pieces have used so far.</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 10 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-10-thirty-five-day-5</guid>
      <link>https://freeston.me/posts/2021-04-10-thirty-five-day-5</link>
      <title>Day Five of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-10-2237-44-663863544714958.jpg"></p><p>Today was a tricky day. The smaller shapes in yesterday's piece reminded me of leaves so I started to explore this idea of falling leaves, which turned into falling blossoms. I like the sense of movement but have been feeling like something is missing and I've run out of time for today.</p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 09 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-09-thirty-five-day-4</guid>
      <link>https://freeston.me/posts/2021-04-09-thirty-five-day-4</link>
      <title>Day Four of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-09-2226-07-583416655741234.jpg"></p><p>Today, experimenting with colours and leaning even more into the variable circle packing for placing the various shapes throughout the canvas. As with <a href='/posts/2021-04-08-thirty-five-day-3/'>yesterday's drawing</a>, a few of the larger shapes' locations are hard-coded (though the actual shape is dictated by the flow field) - a trade-off between the ability for the code to surprise me and my ability to consciously shape the output.</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 08 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-08-thirty-five-day-3</guid>
      <link>https://freeston.me/posts/2021-04-08-thirty-five-day-3</link>
      <title>Day Three of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-08-2059-49-531582619396384.jpg"></p><p>I kept yesterday's idea of having two variations, tried to give the overall piece more structure by doing multiple passes of circle packing, and cranked up the noisiness of the flow field. I'm quite happy with some of the detail and the overall texture of the piece.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 07 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-07-thirty-five-day-2</guid>
      <link>https://freeston.me/posts/2021-04-07-thirty-five-day-2</link>
      <title>Day Two of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-07-2123-00-435263829711662.jpg"></p><p>After a few false starts this evening, I <a href='/posts/2021-03-27-quil-workflow/'>revisited</a> one of the outputs from a few days ago, but decided to only apply the shorter flow lines to the three largest circles and only warp the rest. That separation gives the piece a certain structure that my work often lacks.</p>]]></description>
    </item>
    <item>
      <pubDate>Tue, 06 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-06-thirty-five-day-1</guid>
      <link>https://freeston.me/posts/2021-04-06-thirty-five-day-1</link>
      <title>Day One of Thirty-Five</title>
      <description><![CDATA[<p><img src="/img/thirty-five/2021-04-06-1107-37-465181691510604.jpg"></p><p>After the long Easter weekend and another day off ahead of me, I was feeling rather at peace this morning and so for day one of <a href='/posts/2021-04-05-thirty-five/'>my challenge</a> I channelled the beautiful skies outside my window.</p><p>I'd been feeling the pressure of doing something "good" from the start, so I started developing the code a couple of days ago. I combined a couple of common generative art techniques which I've experimented with before - <a href='https://generativeartistry.com/tutorials/circle-packing/'>circle packing</a> and <a href='https://tylerxhobbs.com/essays/2020/flow-fields'>flow fields</a> - using points around the circles as launch point for flow lines. I didn't really have a sense of what I wanted to achieve but enjoyed tweaking various parameters to get quite varied results.</p><p>I took things in a different direction today, making use of much longer, semi-transparent white lines over a blue background and warping the circles so that they blend into the overall shape. The result feels like a cohesive whole with a satisfying sense of movement.</p>]]></description>
    </item>
    <item>
      <pubDate>Mon, 05 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-04-05-thirty-five</guid>
      <link>https://freeston.me/posts/2021-04-05-thirty-five</link>
      <title>Thirty-Five - A Personal Challenge</title>
      <description><![CDATA[<p><img src="/img/thirty-five/intro.jpg" alt="" /></p><p>When it comes to personal projects, I've often struggled with consistency and taking things through to completion. For that reason, it felt like a huge achievement when I released my game at the end of last year. I kept the scope small and didn't let perfect get in the way of done; it's out and has found a small set of players with whom it has resonated.</p><p>When it comes to creating generative art, I often hit what feels like a local maximum with an idea and struggle to either fully refine it or explore another direction altogether, leaving the work in a sort of limbo state where I neither see it as complete and worth sharing, nor ripe for further exploration.</p><p>I'm going to try something to change that. Tomorrow I am turning 35 years old. I intend to post one piece a day for 35 days, all from the same evolving codebase. I'm not putting any other restrictions on myself - the goal is simply quantity and consistency. Let's see where it takes me.</p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 27 Mar 2021 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2021-03-27-quil-workflow</guid>
      <link>https://freeston.me/posts/2021-03-27-quil-workflow</link>
      <title>Reproduceable Generative Art with Quil and Clojure</title>
      <description><![CDATA[<p><img src="/img/workflow/ring.jpg" alt="" /></p><h2>Context</h2><p>I've been making generative artwork in <a href='https://clojure.org/'>Clojure</a> using <a href='http://quil.info/'>Quil</a> for just over 2 years now. Over time I've evolved a workflow that enables me to experiment quickly whilst reducing the risk of losing interesting results and avenues for exploration.</p><p>Most of the artwork I make is static images, usually with the intention of plotting them using an <a href='https://www.axidraw.com/'>AxiDraw</a>. I usually export images as both <code>png</code> for previewing (and sometimes printing) and <code>svg</code> for plotting. I am also gradually developing <a href='https://github.com/dominicfreeston/penny'>a small library</a> with a focus on manipulating shapes and lines.</p><p>I work in <a href='https://www.gnu.org/software/emacs/'>Emacs</a> connected to a repl using <a href='https://cider.mx/'>CIDER</a>, which means that evaluating the current buffer generates a new sketch. </p><p>It's often useful to be able to <a href='https://www.kovach.me/Infrastructure_of_art.html'>reproduce a particular output</a>, and the way I've been approaching this is to replace Clojure's random functions with an <a href='https://github.com/trystan/random-seed/blob/0acf96c82c32c8b442e79ad0caf0db49cebc6d29/src/random_seed/core.clj'>implementation where the seed can be set</a>, as well as setting the seed for Quil's own <a href='http://quil.info/api/math/random#random-seed'>random</a> and <a href='http://quil.info/api/math/random#noise-seed'>noise</a> functions.</p><p>I'd been exporting images with the <a href='https://tylerxhobbs.com/essays/2016/utilizing-random-number-generator-seeds'>random seed in the filename</a> for a while, but as I tend to continually tweak the code, it often isn't enough to recreate that exact output. I wanted a simple way to save the state of the source code as well.</p><h2>Solution</h2><p>So far I've settled on something like this<a href='#fn-1' id='fnref1'><sup>1</sup></a>:</p><pre><code class="clojure">&#40;ns sketch
  &#40;:require
	&#91;quil.core :as q&#93;
	&#91;clojure.java.io :as io&#93;
	&#91;random-seed.core :refer :all&#93;&#41;
  &#40;:refer-clojure :exclude
	&#91;rand rand-int rand-nth shuffle&#93;&#41;&#41;
  
...

&#40;defn export &#91;&#93;
  &#40;let &#91;name &#40;str sketch-name &quot;-&quot; seed&#41;
        src &#40;:file &#40;meta #'export&#41;&#41;
        dest &#40;str &quot;output/code/&quot; name &quot;.clj&quot;&#41;
        png &#40;str &quot;output/png/&quot; name &quot;.png&quot;&#41;
        svg &#40;str &quot;output/svg/&quot; name &quot;.svg&quot;&#41;
        gr &#40;q/create-graphics
		&#40;q/width&#41; &#40;q/height&#41; :svg svg&#41;&#93;
    ;; Save source
    &#40;io/make-parents dest&#41;
    &#40;io/copy &#40;io/file src&#41; &#40;io/file dest&#41;&#41;
    ;; Save png
    &#40;set-random-seed! seed&#41;
    &#40;draw&#41;
    &#40;q/save png&#41;
    ;; Save svg
    &#40;set-random-seed! seed&#41;
    &#40;q/with-graphics gr
      &#40;draw&#41;
      &#40;.dispose gr&#41;&#41;&#41;
  &#40;q/exit&#41;&#41;
</code></pre><p>Exporting a sketch, including copying the source, now means replacing the <a href='http://quil.info/api/environment#defsketch'>draw function in the sketch</a> with this export function, without the need for extra infrastructure and setup. It does require that a) there is a single file we want to save a snapshot of and b) the export function is within that file (as it uses the metadata of the export function itself) - but that suits me well at this point. <ol class='footnotes'><li id='fn-1'>I initially worked with Quil's <a href='https://github.com/quil/quil/wiki/Functional-mode-(fun-mode'>functional-mode middleware</a> (because Clojure), but moved away from it as I do all the rendering in a single draw call anyway.<a href='#fnref1'>&#8617;</a></li></ol></p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 07 Oct 2020 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2020-10-07-the-wallslider</guid>
      <link>https://freeston.me/posts/2020-10-07-the-wallslider</link>
      <title>The Wallslider Is Out Now</title>
      <description><![CDATA[<p>I have finally completed and shipped a game.</p><p><img src="/img/wallslider/logo.png" alt="" /></p><p><a href='https://www.thewallslider.com'>The Wallslider</a> is my attempt at the kind of mobile game I've loved the most. Difficult but fair, short repeatable play sessions, bonus points if playable with one hand so I can hold on when on a moving train. Something that seems impossible at first but can be mastered over time. Something from an age before "free-to-play" and endless micro transactions.</p><p>It's essentially an endless runner except rather than just reacting to obstacles, you propel yourself upwards and will slide back if you stop, so it requires more constant input but it also maybe requires a bit more deliberation and planning than just pure reactions.</p><p>A couple of friends' first reactions were "it's the next Flappy Birds", which is flattering despite my reservations about that game. I understand, it has that endless tapping energy, but I like to think The Wallslider is a bit more subtle than that. You've got control over your jump height, your sliding speed and a grappling-hook you can bail out, all by varying the rhythm and length of your presses. Also Flappy Bird was free, early and made people feel that Nintendo warmth, so I'm not exactly expecting that kind of cultural relevance.</p><p>Other things people have said include "it's a really fun game" and "I hate you", and one friend got so good at it he obliterated my high scores throughout the beta, all of which makes me feel warm and fuzzy and like I've achieved my goal.</p><p>Another common reaction is "I love the music", and if that's yours, I'm right there with you! I knew my colleague <a href='https://twitter.com/ouchadam'>Adam</a> had done some chip tunes so I asked him about his music, but when I heard his track <a href='https://soundcloud.com/ouch-fire/ouch-fire'>Sentry</a>, I was blown away. It feels to me now like it was written especially for The Wallslider, though it predates it by 7 years. I'm so grateful he let me use it.</p><p>My favourite games in this space include <a href='http://www.canabalt.com/'>Canabalt</a>, <a href='http://www.laserdog.co.uk/alone'>Alone</a> and the masterpiece that is <a href='https://superhexagon.com/'>Super Hexagon</a>. All of them have a strong identity, great gameplay and awesome sound and music. If you like them too and you enjoy a retro aesthetic paired with some 8-bit inspired drum and bass, I like to think you'll get something out of The Wallslider.</p>]]></description>
    </item>
    <item>
      <pubDate>Wed, 26 Feb 2020 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2020-02-26-vector-fields</guid>
      <link>https://freeston.me/posts/2020-02-26-vector-fields</link>
      <title>Vector Fields Exploration</title>
      <description><![CDATA[<p><div align=center> <img src="/img/vectorfields/orange.jpg" width=70% /> </div></p><p>A budding generative artist will, sooner or later, play with <a href='https://en.wikipedia.org/wiki/Vector_field'>vector fields</a><a href='#fn-1' id='fnref1'><sup>1</sup></a>.</p><p><a href='https://tylerxhobbs.com/'>Tyler Hobbs</a>, one of my favourite generative artists, recently wrote a <a href='https://tylerxhobbs.com/essays/2020/flow-fields'>good introduction</a> that prompted me to make that time be now. All the images in this post are created using roughly the same program based on a field populated with perlin/simplex noise and tweaking a dozen or so parameters.</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/fur-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/fur-2.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/fur-3.jpg" />   </div> </div></p><p>By restricting the starting point of the flow lines and letting them run long in a chaotic flow field we get structured yet dynamic images:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/smoke-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/smoke-2.jpg" />   </div> </div></p><p><div class="row">   <div class="item"> 	<img src="/img/vectorfields/bw-2.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/bw-3.jpg" />   </div> </div></p><p>Maintaining the high step-size through the noise field but ensuring the field still flows in roughly one direction leads to long lines quickly converging into the main paths through the field. Combine with highly saturated colors for some 80s sci-fi vibes:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/neon-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/neon-2.jpg" />   </div> </div></p><p>Swap for filled shapes defined by short lines for some winding vine-like effects:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/plant-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/plant-2.jpg" />   </div>   <div class="item">   <img src="/img/vectorfields/plant-3.jpg" />   </div> </div> <div class="row">   <div class="item">   <img src="/img/vectorfields/wp-red.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/wp-green.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/wp-purple.jpg" />   </div> </div></p><p>Extend the length of the lines defining some heavily layered shapes for some dynamic dreamscapes:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/dream-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/dream-2.jpg" />   </div> </div> <div class="row">   <div class="item"> 	<img src="/img/vectorfields/dream-3.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/dream-4.jpg" />   </div> </div></p><p>Pairing flow lines at random and layering resulting shapes can create some interesting texture with a sense of light peering through, almost like stained glass, though here using random short lines and pairing them may achieve a similar effect more simply:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/blue-0.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/blue-1.jpg" />   </div> </div> <div class="row">   <div class="item"> 	<img src="/img/vectorfields/blue-2.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/blue-3.jpg" />   </div> </div></p><p>Different combinations of layered semi-transparent shapes from grouping multiple flow-lines create interesting watercolor paint-like effects:</p><p><div class="row">   <div class="item">   <img src="/img/vectorfields/paint-1.jpg" />   </div>   <div class="item"> 	<img src="/img/vectorfields/paint-2.jpg" />   </div> </div></p><p>Lots more to explore, but some exciting and varied initial results from a fairly straightforward system. <ol class='footnotes'><li id='fn-1'>Also, apparently start with black and white images and eventually "discover colors" then talk or write about how hard it is to use well. Which, considering some of the choices made here, is a fair point.<a href='#fnref1'>&#8617;</a></li></ol></p>]]></description>
    </item>
    <item>
      <pubDate>Tue, 31 Dec 2019 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2019-12-31-retrospective</guid>
      <link>https://freeston.me/posts/2019-12-31-retrospective</link>
      <title>Retrospective</title>
      <description><![CDATA[<p>I started my Clojure journey with Advent of Code 2018, with the long term and nebulous goal of <a href='https://blog.bradfieldcs.com/in-2017-learn-every-language-59b11f68eee'>learning every language</a>. Separately I also was getting more curious about computer and generative art as a potential new creative outlet and was inspired to use our newly acquired pen plotter to produce a physical output, so I found some <a href='https://mattdesl.svbtle.com/pen-plotter-1'>very helpful resources</a> and started trying things out. I didn't achieve much there but I made one thing that made me want to keep going:</p><p><img src="/img/retrospective/lines.jpeg" alt="" /></p><p>Unable or unwilling to commit to Javascript based tools, struggling to focus on learning Clojure without an obvious goal in mind, I eventually came across <a href='http://www.quil.info'>Quil</a><a href='#fn-1' id='fnref1'><sup>1</sup></a> and realised I could work towards two goals at once. It's turned out to be an incredibly rewarding and somewhat successful endeavour. Below are a few of the things I've made this year.</p><p><img src="/img/retrospective/cards.jpeg" alt="" /> I first started with laying out grids of shape and playing around with <a href='/posts/2019-06-14-random-lines/'>scaling and rotating such repeated shapes</a>, which made for some quite attractive birthday cards.</p><p><img src="/img/retrospective/inkblots.jpeg" alt="" /> One of the first times I went from idea to execution in the space of an evening, I created this drawing inspired by the inkblot patterns on my wife's wedding dress.</p><p><img src="/img/retrospective/curves.jpeg" alt="" /> At one point, just throwing random curves at the canvas, I found myself creating images that I couldn't plot because I'd accidentally kept the fill color. I played around with converting the bitmap output to vectors and playing with Inkscape's tools and got some fairly interesting results quite far from the original, though I don't see myself going down this manual route again any time soon.</p><p><img src="/img/retrospective/perp.jpeg" alt="" /> I played around with growing a drawing using perpendicular offshoots off existing lines, an idea I might go back to once I can get over the fact it's <a href='http://www.complexification.net/gallery/machines/substrate/index.php'>already been done to near perfection</a>.</p><p><img src="/img/retrospective/map.jpeg" alt="" /> I'd been wanting the option to fill shapes or crop a drawing to a shape and finally did it to produce this. I have begun growing a <a href='https://github.com/dominicfreeston/penny/'>small library</a> for those kinds of operations.</p><p><img src="/img/retrospective/space_invader.jpeg" alt="" /> Although not generative, it was fun to come up with an idea for my brother's Christmas gift and have the tools and the skills to be able to produce it. <ol class='footnotes'><li id='fn-1'><a href='https://tylerxhobbs.com/essays/2019/code-goes-in-art-comes-out'>Tyler Hobb's talk at Clojure/conj</a> is worth a watch.<a href='#fnref1'>&#8617;</a></li></ol></p>]]></description>
    </item>
    <item>
      <pubDate>Fri, 14 Jun 2019 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2019-06-14-random-lines</guid>
      <link>https://freeston.me/posts/2019-06-14-random-lines</link>
      <title>Random Lines</title>
      <description><![CDATA[<p>I've been toying with Clojure and Quil to generate drawings that I can then draw with a pen plotter. The most successful thing I've managed to do so far is a little program that:</p><ol><li>defines a shape by generating a random set of lines within a small grid</li><li>repeats that shape in a larger grid, randomly varying its scale and rotation</li></ol><p>The grids and repetition create a pleasing sense of regularity whilst the randomness leaves just enough room for some surprises. I find myself looking for extra patterns, even in the aspects I know to be random.</p><p>Every time you load this page you'll get a different image below: <img src="https://protected-brook-19426.herokuapp.com/" alt="" /></p><p>(It may take a while to load because it's on a free heroku instance and spins down after 30min of inactivity)</p>]]></description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2019 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2019-05-16-procrastivity</guid>
      <link>https://freeston.me/posts/2019-05-16-procrastivity</link>
      <title>Procrastivity</title>
      <description><![CDATA[<p>Of course this site was going to become it's own source of procrastination. <a href='http://cryogenweb.org/'>Cryogen</a> works quite well as it is, but there is room for improvement (including a few welcoming 'help wanted' labels in the issues). One of the reasons for picking it was for me to use some more Clojure, plus I've been wanting to make some more open source contributions. Lucky for me then, there were some issues to distract me.</p><h3>XML Generation</h3><p>Having deployed this site for the first time, I pointed my <a href='https://feedwrangler.net/'>RSS reader</a> to my new feed and then... saw an empty title. Looking at the raw feed revealed a potential cause: lots of new lines, including before the content of the tags. Digging through the code lead me to <a href='https://github.com/yogthos/clj-rss'>clj-rss</a>, which in turn relies on Clojure's own <a href='https://clojure.github.io/clojure/clojure.xml-api.html'>clojure.xml</a>. So why the issue?</p><p>The great thing about Clojure being open source, is you can look at it<a href='#fn-1' id='fnref1'><sup>1</sup></a>. Looking at <a href='https://github.com/clojure/clojure/blob/b9b1a094499b69a94bd47fc94c4f082d80239fa9/src/clj/clojure/xml.clj#L111'><code>emit</code></a> reveals what can only have been intended as a debugging helper - it uses <code>print</code> rather than returning a string or writing to a file. It does none of what would be required for proper xml support like escaping strings. It also adds new lines everywhere (via <code>println</code>), including in tags containing text. There's our issue! It's changing the content of the tag: it now starts and ends with an extra new line.</p><p>There's better alternatives, of course, most notably <a href='https://github.com/clojure/data.xml'>data.xml</a><a href='#fn-2' id='fnref2'><sup>2</sup></a>, but I'm confused as to why something like <code>emit</code> would ship in Clojure's core libraries. It might be that using access-control is less typical in Clojure code and doc strings are what's primarily used to communicate intent. Regardless, my proposed change to using data.xml in Cryogen was promptly accepted, deployed and bubbled up through to Cryogen itself.</p><h3>Markdown Parsing</h3><p>Like with many static site generators, posts for this site are written in Markdown. You may have already noticed I enjoy peppering my writing with plenty of links and asides via footnotes<a href='#fn-3' id='fnref3'><sup>3</sup></a>. A previous draft of a similar post quickly put <a href='https://github.com/yogthos/markdown-clj'>markdown-clj</a> through its paces and surfaced issues with multiple types of links in the same paragraph.</p><p>Not much to expand upon here, but it was a useful exercise in figuring out somebody else's Clojure code and another opportunity to contribute back. It has also raised some questions in my mind around <a href='https://puredanger.github.io/tech.puredanger.com/2013/08/31/clojure-and-testing/'>Clojure and testing</a>. Part of the language's appeal for me has been its underlying philosophy and it's going to be interesting to see which parts continue to resonate.</p><h3>Future Contributions</h3><p>My interactions with the <a href='https://github.com/orgs/cryogen-project/people'>maintainers</a> of Cryogen and its dependencies have been a delight so far, and so I've decided to <a href='https://github.com/cryogen-project/cryogen-core'>take on</a> one of the <a href='https://github.com/cryogen-project/cryogen-core/issues/98'>previously raised issues</a>. Fixing and expanding a static site generator is not exactly what I'd planned to spend these couple of weeks on, but it's been both educational and rewarding. <ol class='footnotes'><li id='fn-1'>As an iOS developer, being able to look at source code is still a relative novelty.<a href='#fnref1'>&#8617;</a></li><li id='fn-2'>It is at version 0.2.0-alpha6 at the time of writing, but seems stable enough. I'm under the impression Clojure libs have a tendency to stay sub 1.0 for a long time.<a href='#fnref2'>&#8617;</a></li><li id='fn-3'>I've never had an idea I couldn't expand on or wander away from.<a href='#fnref3'>&#8617;</a></li></ol></p>]]></description>
    </item>
    <item>
      <pubDate>Sat, 04 May 2019 00:00:00 +0000</pubDate>
      <guid>https://freeston.me/posts/2019-05-04-its-alive</guid>
      <link>https://freeston.me/posts/2019-05-04-its-alive</link>
      <title>It's (a)live!</title>
      <description><![CDATA[<p>It's been a long time, but I have a website again. It's not much, but it's mine. I think it's a tech blog, time will tell.</p><h3>About me</h3><p>I'm an iOS developer by day, so I'd expect some related topics. I've been toying with Clojure for a little while now. I use <a href='http://www.quil.info/'>Quil</a> to generate line drawings for a pen plotter. Through Clojure I started using Emacs which has kind of become a hobby <a href='https://github.com/dominicfreeston/emacs-config'>in itself</a>. I'm also quite into games, board and video. I sometimes play around making them in Lua using <a href='https://love2d.org/'>LÖVE</a> or <a href='https://www.lexaloffle.com/pico-8.php'>PICO-8</a>.</p><h3>This site</h3><p>This site is generated using <a href='http://cryogenweb.org/'>Cryogen</a>, a nifty static site generator written in Clojure. It ships as a <a href='https://leiningen.org/'>Leiningen</a> template, so it was easy to get started. I didn't use Jekyll or Hugo or something else you've heard of because I'm a hipster, and it's more likely I'll tinker with it.</p><p>The <a href='https://github.com/dominicfreeston/freeston-dot-me'>template</a> for the site is lovingly hand-crafted by me in a minimalist style. That's to say, I created an empty folder and added files until Cryogen stopped giving me errors. I copied over bits of the existing templates until the content I wanted appeared, then added just enough CSS to make my eyes stop hurting. It's unlikely to work with a different config.</p>]]></description>
    </item>
  </channel>
</rss>
