Fedran2024-03-28T17:39:17Zhttps://d.moonfire.us/tags/fedran/D. MoonfireCreative Commons Attribution-NonCommercial-ShareAlike 4.0 InternationalNew Site Colors2024-02-24T06:00:00Zhttps://d.moonfire.us/blog/2024/02/24/new-site-colors/I decided to rework the colors of my websites, both for d.moonfire.us and future work on fedran.com. Along the way, I made a library to package the theme work and got to play with CSS variables.
<p>I should have been working on something else today, but a series of events lead me down a path of reworking how I implemented my themes here on <a href="https://d.moonfire.us/">https://d.moonfire.us/</a> and <a href="https://fedran.com/">https://fedran.com/</a>.</p>
<p><em>I have not updated the color themes on Fedran at this point.</em></p>
<p>In specific, it was someone mentioning they didn't like my dark theme on their recently announced blogroll. Now, there is absolutely nothing wrong with someone not liking my sense of colors or even how I code websites, but a desire to change the colors has been sitting in the back of my head for a few months. That meant that the commentary reminded me of my own desires to change it and that lead into my fixating on redoing the colors.</p>
<h2>Color Preferences</h2>
<p>One of the problems is that I have a fondness for mono- and bichromatic color themes. You can see that on my covers, but I also realize that it creates rather plain (e.g., uninteresting) site theme. I started to really notice it once I started using <a href="https://github.com/catppuccin/catppuccin">Catppuccin</a> as one of my most common UI themes. There were colors on the screen! Multiple of theme!</p>
<p>And I started wanting a few distinct of my own.</p>
<p>At the same time, I continue to struggle with contrasts. When I was younger (teenager and 20s), I loved drawing on quadraile graph paper. But somewhere in my 30s, I started having trouble because the lines were making it hard for me to see my writing. So I went on a few adventures to find lighter lines and evetually switched to dotted grid pages. Then in my 40s, even those became too dark and I had to switch to the same thing my father used: plain white paper.</p>
<h2>POV Colors</h2>
<p>Related to this is my decision that every point of view in Fedran had a different color. I like that idea, mainly because I <em>love</em> colors, I'm just not great with seeing differences. This is why <a href="https://fedran.com/sand-and-blood/">Sand and Blood</a> has a different color set than <a href="https://fedran.com/allegro/">Allegro</a>.</p>
<p>Each POV has a color hue and everything else is built off of that using <a href="https://atmos.style/blog/lch-color-space">LCH colors</a>. When I switched the covers to be bichromatic, I made the second color always be the contrast (rotate 180 degrees) from the primary color.</p>
<p>Easy huh?</p>
<p>However, this entire excercise pointed out that most people can't tell the difference between say 220 and 225 hue, so I really should spread out the colors a lot more. Even if I say a 6 degree difference in hues, that would limit me to sixty POVs. (Of course, since I'm still somewhat burned out, sixty is a lot right now.)</p>
<p>So, I'm going to change it so each POV color is three colors: the primary color I had before and then two accent colors (which the first will be the contrast color for the existing assigned colors). I'm not quite ready for the full gaumt of colors, but maybe increasing them to three would give me more than enough space and still cater to my reduced color palette.</p>
<p>It also harkens back to CGA colors, which is the first colors I saw on computers.</p>
<h2>Segmenting Colors</h2>
<p>The general idea was to break the color space into ten segments, numbers from zero to nine. The first color (<code>c0</code>) would be based on the hue and the others would be 36° from that so they are evenly spread across the entire range of hues.</p>
<p><img src="./color-grid-220.png" class="block" alt="Color Grid for 220°" /></p>
<p>If the hue changes (like the POV hues), then everything else rotates to fit.</p>
<p><img src="./color-grid-20.png" class="block" alt="Color Grid for 20°" /></p>
<p>As you can see in the above images, there is also ten ranges of brightness (combination of saturation and lightness) that goes from zero to nine with zero being a not-quite-black version of the color and nine being a not-quite-white version.</p>
<p>This effectively gives me a wide range of colors that aren't very close to each other but still a small enough set I'm not struggling with the differences of 218° and 223°.</p>
<h2>CSS</h2>
<p>Because I've really embraced CSS variables instead of going directly to SASS or LESS, this entire thing uses various CSS variables such as <code>--color-priduck-c0b0</code> and <code>--color-priduck-c9b9</code>. They use <code>calc()</code> and <code>lch()</code> to build the colors from the base hue of <code>--color-priduck-hue</code>.</p>
<p>Eventually, I hope to create some symbolic ones like <code>--color-priduck-comment</code> or something that would allow customizations.</p>
<p>This will also lead into the <code>rgb()</code> colors that I need to do the Fedran covers.</p>
<h2>Libraries</h2>
<p>I ended up writing two little NPM packages to support these and let me try it out. These are not even remotely documented because… I would consider them alpha until I get Fedran integrated with them. By then, I should have something I feel is “right” but also expand it out into the other components I need such as the color-rotation code to make the covers and other stuff.</p>
<p>Needless to say, if I like this, it will take me about six months to a year to finish integrating it into my system. Which means I want to make sure this is the direction I want to go.</p>
<p>I also decided to call this the Priduck Color Theme, because “priduck” sounded funny, doesn't have a lot of search hits, and it reminds me a lot of the <a href="https://www.youtube.com/channel/UC1KLPSDD6JT-PptihEqAJ2Q">Useless Duck Company</a>, a set of hilarious shorts about inventing.</p>
<h3>@priduck-color-theme/base for Node</h3>
<p><a href="https://src.mfgames.com/priduck-color-theme/priduck-color-theme-base-js">https://src.mfgames.com/priduck-color-theme/priduck-color-theme-base-js</a></p>
<p>Naturally, trying to build all of these was a little tedious so I wrote an ad-hoc programs to generate the color schemes using CSS variables. Then put it into a NPM package because I don't like copy/pasting things when I know I'm going to be tweaking it over time (including adding symbolic colors so I can have a default colors for language keywords, surfaces, and accents).</p>
<p>This lets me just include it into the CSS files as needed.</p>
<pre><code class="language-css">@import "~@priduck-color-theme/base/colors.css";
:root {
--color-priduck-hue: 220;
}
</code></pre>
<h3>@priduck-color-theme/theme for Node</h3>
<p><a href="https://src.mfgames.com/priduck-color-theme/priduck-color-theme-theme-js">https://src.mfgames.com/priduck-color-theme/priduck-color-theme-theme-js</a></p>
<p>I also wrote another because there isn't a good way to write a DRY version of CSS themes that can handle default values, the browser providing <code>prefers-color-scheme</code> and <code>prefers-contrast</code>, and setting them via attributes in various combinations. So I wanted to be able to provide six files (dark/light and more/less contrast for both of those).</p>
Fedran Infrastructure Redux2023-06-27T05:00:00Zhttps://d.moonfire.us/blog/2023/06/27/fedran-infrastructure-2/Just a follow up on a few things I had to do to get my Fedran infrastructure behaving better and not chewing up time and bandwidth once a day.
<p>I know I said that I was going to work on writing after working on <a href="/blog/2023/06/24/fedran-infrastructure/">the previous post</a>, but I tried to speed up the pipelines because an hour was overwhelming and bothered me.</p>
<p>Thanks to a bit of obsession, I figured it out.</p>
<p>The bulk of the pipeline was spent download and building Nix packages. This normally isn't a problem, but I want to be able to run an agent in my home lab where I'm charged for bandwidth overages. Pulling down half a gig of packages every time I built my website was also not being a good steward of the Internet as a whole.</p>
<p>I had bookmarked a link to kotatsuyaki's <a href="https://blog.kotatsu.dev/posts/2023-04-21-woodpecker-nix-caching/">Locally Cached Nix CI with Woodpecker</a> which was based on <a href="https://kevincox.ca/2022/01/02/nix-in-docker-caching/">Kevin Cox's work</a> and tried it a couple of times. I usually got hung up on switching from Docker to Podman but eventually got it mostly working, hit some snags, and found a slightly-less-than-optimal approach instead.</p>
<h2>Lazy Configuration</h2>
<p>It took me a day to figure out how to get Podman working with my setup. Naturally, OCI images in Nix change name so it was <code>docker-woodpecker-server</code> in Docker and <code>podman-woodpecker-server</code> on Podman. This meant I had to also switch the various systemd links that tie in changing secrets with restarting the OCI images.</p>
<p>As usual, once I realized I was going back and forth (usually on the third time), I decided to automate that.</p>
<pre><code># woodpecker-agent.nix
{
config,
pkgs,
lib,
...
}: let
tag = "next-eaae6b44c7";
container =
if config.virtualisation.podman.enable
then "podman"
else "docker";
in {
sops.secrets = {
woodpecker-ci-agent = {
restartUnits = ["${container}-woodpecker-ci-agent.service"];
};
};
</code></pre>
<p>I'm not fond of Nix as a language, but it was nice being able to have it pick up which configuration was set up properly and then rename the various systemd units as appropriate.</p>
<h2>Mounting Nix Store</h2>
<p>The crux of the problem was storing Nix packages so I didn't have to download them every time I built the package. This is really important when I start doing mass changes to my writing projects since one of those causes ~137 pipelines to be triggered. Since each one uses an identical <code>flake.lock</code> (because of the Rust CLI), caching those packages also means that it can generate each of the PDFs and EPUBs automatically when I update packages, change style, or need to rebuild things.</p>
<p>Originally I tried the example in the above link and it worked beautifully. I did have to make the pipeline trusted, but I run my own CI server and I don't build pull requests, so I have that locked down to avoid too much security exposure.</p>
<pre><code># .woodpecker.yaml
pipeline:
run-greet:
image: nixos/nix
commands:
- echo 'experimental-features = flakes nix-command' >> /etc/nix/nix.conf
- nix run --store unix:///mnt/nix/var/nix/daemon-socket/socket?root=/mnt .#greet -L
volumes:
- /nix:/mnt/nix:ro
</code></pre>
<p>I do think I may have had better luck if I included Kevin's command in the above link.</p>
<blockquote>
<p>I have seen some issues when using –store. I found that this can be fixed by additionally passing –eval-store local.</p>
</blockquote>
<p>Though by the time I realized I should have tried that, I found a working solution and needed to stop messing with an incremental change without significant improvement over what I had.</p>
<p>When I migrated my Fedran pipeline over to the above <code>--store</code> implementation, it blew up with being unable to link DLLs/shared libraries. First it was <code>sodium23</code>, then <code>lowdown</code>, then something else. Each time, I added more packages to the build until I hit <code>libnixeval.so</code>. That one… I couldn't fix.</p>
<p>The main problem was the <code>run-greet</code> pipeline didn't need to call the <code>nix</code> executable, but I was using <a href="/tags/nix-standard/">Standard</a> which does. That means, I couldn't use <code>std //cli/apps/default:run</code> to run anything which basically meant I had to use <code>cargo build</code> which negated the entire purpose of using Nix packages to cache. I also couldn't use <code>nix run .</code> to take advantage of the Nix caching.</p>
<p>In the end, I switched back to Docker but with Kevin's first suggestion: just create a volume in Docker to share the Nix store. This worked out well… but I had to make a tweak from Kevin's original suggestion:</p>
<pre><code># .gitlab.yaml (I don't remember what it is called anymore)
[[runners]]
executor = "docker"
[runners.docker]
volumes = ["/nix"]
</code></pre>
<p>I found it worked better if I used a named volume:</p>
<pre><code># .woodpecker.yaml
pipeline:
deploy:
image: nixpkgs/nix-flakes
commands:
- nix develop --command ./src/website/scripts/ci.sh
when:
event: [push, manual, cron]
branch: main
volumes:
- woodpecker-nix-store:/nix # named instead of just `- /nix`
</code></pre>
<p>And that worked beautifully. The build time when down from 48 minutes for the last run to 6 minutes at the most current one. Plus it barely downloaded anything thanks to using Crane for Rust in Nix, and the general package management. If I created a second store to keep the Git repositories and only did a <code>git pull</code> instead, I could shave it down even more.</p>
<h2>Cleanup</h2>
<p>It did occur to me that if I left what I figured out as-is, sooner or later I would run out of space. (I also was reminded by I always create a dedicated <code>/var/lib/docker</code> partition in this). So on my nightly job, I added this stanza to my <code>.woodpecker.yaml</code> file (which I haven't tested very well):</p>
<pre><code># .woodpecker.yaml
pipeline:
clean:
image: nixpkgs/nix-flakes
commands:
- nix-collect-garbage --delete-older-than 15d
when:
event: [cron]
branch: main
volumes:
- woodpecker-nix-store:/nix
</code></pre>
<p>If I did it right, then it should keep everything cleaned up and tidy. I'll find out in a month or so if that is true.</p>
<h2>Checkout</h2>
<p>One thing to be said about having so many project pipelines is that I hammer my system when I do a mass change (updating the locks for example). This meant I encountered a strange bug where Woodpecker's checkout plugin starts to fail somewhere around the tenth rapid-fire pipeline.</p>
<p>To get around it, I switched from using the built-in clone to do it manually:</p>
<pre><code># .woodpecker.yaml
skip_clone: true
pipeline:
clone:
image: alpine/git
commands:
- git clone https://fedran:$GITEA_TOKEN@src.mfgames.com/$DRONE_REPO.git . --depth 1
- git checkout $DRONE_COMMIT
secrets:
- gitea_token
when:
event: [push, manual, cron]
branch: main
</code></pre>
<p>Since I put it in, I haven't seen check out failures due to being unable to get the user name and password from the prompt. I could have also used <code>nixpkgs/nix-flakes</code> instead of <code>alpine/git</code>, but didn't. This works and it's fast.</p>
<h2>What's Next</h2>
<p>I really need to write. I got a closure point. Everything works, I wrote issues up for the ones that aren't breaking, so I can stop obsessing and instead focus on the 10 kwd obligation I have by the end of the month. Which is to say… probably not going to happen but I'm going to still try.</p>
Fedran Infrastructure2023-06-24T05:00:00Zhttps://d.moonfire.us/blog/2023/06/24/fedran-infrastructure/In the last month, I've been doing a lot of writing and programming. I also finished a good-sized around of "fun coding" with Fedran.
<p>In the first weeks of March, June, September, and December, life gets complicated for my day job. Usually that means the pressure gathers in intensity in the preceding weeks and then winds down after the quarterly release.</p>
<p>It is time when my other obligations start to press into my attention and I'm too busy to focus on them. Naturally that means as the release winds down, I try to get focus on the others.</p>
<p>This month, I managed to get twenty thousand words on a commissioned novel. I also stumbled into a few things on the Internet that set off my fixation and I ended up working on them for a few weeks as a “play coding” to relieve the stress. This month, it was almost entirely related to <a href="//fedran.com/">Fedran</a>, my fantasy setting that I also use to create what I'm hoping is a full-featured website suitable for spoilers, “who is this character again,” and just background stories.</p>
<h2>Fedran Monorepo</h2>
<p>Some time ago, I decided to bulk most of the “backend” of Fedran to a single Git repository. I'm still keeping my sources (all the stories, novels, and poetry) in individual repositories though I did go through the exercise to see if I wanted it (I do, there are too many benefits). But the infrastructure is a different story.</p>
<p>There isn't much there right now, just a standard directory structure to locate the files, the <a href="/tags/nitride/">Nitride</a> website, and a Rust CLI which sets up the individual stories in a standard configuration, lets me do queries across the projects, and starts to help me coordinate everything together.</p>
<p>Both have built up over the years as I've tried to automate one problem after the other. Moving them into a single repository meant I needed to back out a lot of the cruft that was to coordinate the multiple repositories. I didn't have to manually build the Rust CLI anymore, I didn't need to integrate download the projects into it, I didn't need all the configurations and tokens because there was now one official layout and structure to work against.</p>
<p>Last last month, I got the website migrated over. This week, I got the CLI fully integrated, actually building, and doing things. This means when I edit a chapter to add content warnings or add details, the website deployment will pick up the changes without me having to remember (e.g., not getting it done more twice or thrice a year).</p>
<p>It does add a half hour to the build process because I'm apparently incapable of picking a single language to work on and I haven't figured out caching on my <a href="/tags/woodpecker-ci/">Woodpecker CI</a> server, so it downloads the entire repository, a half GB of Rust packages, another quarter of NuGet packages, and about the same in Node packages to build it.</p>
<p>That I can work on.</p>
<p>This took a while, mainly because I was struggling to get it integrated into a standalone and remove the bulk of the overhead I needed when it was separate.</p>
<h2>NixOS and Standard</h2>
<p>Last week, while wandering around the internet, I stumbled on <a href="https://std.divnix.com/">Standard</a>, a setup for NixOS flakes (like I use for Fedran's monorepo) that is opinionated but also seems to fit a lot with my thing.</p>
<p>That was a fun few days (four) to migrate the Fedran site over, and it fixed some problems I was having in general (read, I actually have the CLI integrated into the build now).</p>
<p>The success means I want to change over my other infrastructure repository which drives most of my home lab but… I need to say no to that until after August.</p>
<p>But, one thing that really stuck with me is that it hits the same buttons that I found when I was reading about Buck2 and Bazel, two other monorepo systems that fit well with a lot of professional and personal development going on in my life. Plus, I just like typing this:</p>
<pre><code>std //cli/apps/default:run
</code></pre>
<p>or</p>
<pre><code>std //website/app/default:build
</code></pre>
<p>And have it do all the right things including getting all the dependencies. I can easily see that tying in my aggregate books, timelines, and other stuff nicely into a single unified system.</p>
<h2>Future Plans</h2>
<p>I like building Fedran's infrastructure as much as writing. More so lately because I burned out a little bit and need to work on finishing <a href="/tags/nor-curse-be-found/">Nor Curse Be Found</a> and <a href="/tags/second-hand-dresses/">Second-Hand Dresses</a>.</p>
<p>Speaking of <em>Dresses</em>, I'm down to a single editing question but that ties into a <em>different</em> program I need to work on, rebuilding my calendar system so it can play with C# and Rust. I've been using my Typescript based on for about a decade now and I have a huge list of things that need to work.</p>
<p>Who knew an editor question of “what day is it” would trigger that paralysis, but I want to solve it because one of the things I lost with my migration to Nitride was my (awesome) timeline functionality. I was proud of that and want it back.</p>
<p>The calendar is also critical for my constraint system. Because I'm coordinating across multiple process, and I had a terrible time with <a href="/tags/raging-alone/">Raging Alone</a>'s documentation process, I realized I need to have something that lets me say things like “this character is eight years older than this one” or “this happens two months after the events of this story”.</p>
<p>(I also need a map, but I'm trying really hard not to think about that.)</p>
<h2>Nor Curse Be Found</h2>
<p>Speaking of <em>Nor Curse Be Found</em>. I hit a little bit of a writer's block on the current chapter and I'm not happy with it. But work and my writing obligations are making it difficult to focus on it, which is why I haven't done much with it lately. I can only have so many writing projects going on and writing that pays bills has a higher priority over writing that makes me feel good.</p>
<h2>Reddit</h2>
<p>While Reddit was imploding, I stumbled onto a post in /r/fantasy asking for resident authors. Since I've been commenting off and one for a few years (and being good about not saying "read my book!"), I decided to <a href="https://www.reddit.com/r/Fantasy/comments/14bwwws/comment/johz1em/">throw my hat into the ring</a>. Not sure what would come of it, but it wouldn't hurt since right now <a href="/tags/flight-of-the-scions/">Flight of the Scions</a> currently has one review on Amazon and zero reviews on Goodreads (and just about nowhere else).</p>
<h2>Self-Published Fantasy Blog Off</h2>
<p>Over the years, I've withdrawn from both Facebook and Twitter. One of the conquences of this action is that I don't know about a lot of things going on, but one thing I've been occasionally checking has been the <a href="https://en.wikipedia.org/wiki/Self-Published_Fantasy_Blog-Off">Self-Published Fantasy Blog-Off</a>.</p>
<p><a href="/tags/sand-and-blood/">Sand and Blood</a> was a semi-finalist in the first one and I felt I was <em>so close</em> to getting to at least finalist. I lost the finalist for <a href="https://www.grimdarkmagazine.com/review-the-thief-who-pulled-on-troubles-braids-by-michael-mcclung/">The Thief Who Pulled on Trouble's Braids</a> who would eventually be the winner.</p>
<p>But I was hoping that maybe <em>Flight of the Scions</em> could finally have a chance. So I was waiting for the announcement from <a href="http://www.marklawrence.buzz/">Mark Lawrence</a> but it never came. Last night, when I decided to check one more time, I saw the reason.</p>
<blockquote>
<p>SPFBO 9 is closed. We reached the 300 entries in 41 minutes.</p>
</blockquote>
<p>Without watching for when the next round comes around, I might have to just hang up my hat on trying to make another SPFBO and just chalk it up to an “almost win” with <em>Blood</em>.</p>
<h2>What's Next?</h2>
<p>Wel, I need to put down the programming hat for a while because we're coming up to the end of the month and I need to write another ten thousand words on my end of month obligation. The beginning of the month will be my commissioned novel (hoping to get 10-20k words by the 15th).</p>
<p>That means my next “fun break” is in about three weeks. I need to work on the <a href="/tags/typewriter-press/">Typewriter Press</a> website because I published another book for an author last week and I need to do my due diligence to help them sell as many copies as possible.</p>
A Week of Dependencies plus Nor Curse Be Found 132023-01-29T06:00:00Zhttps://d.moonfire.us/blog/2023/01/29/a-week-of-dependicies/To write a chapter in *Nor Curse Be Found*, I ended up spending three days working on projects and tasks that needed to be done to provide the tools I use while writing.
<p>I'm trying to get get back to the one-week iterations/sprints for my personal projects. As one of my goals for the year, I want to write at least one short story or a chapter a month. “At least” being the goal since I want to write more, but writing <a href="https://fedran.com/">Fedran</a> is still a struggle because of burnout, <a href="/tags/entanglement-2021/">entanglement</a>, and just life.</p>
<h2>Markdowny</h2>
<p>So I dedicated this week to writing chapter thirteen of <a href="/tags/nor-curse-be-found/">Nor Curse Be Found</a>, but in the process of setting it up, I finally hit the point where bugs in <a href="/tags/markdown/">Markdowny</a> were too much for me. The main one is that I used the wrong shebang in the scripts but didn't realize it until I switched to <a href="/tags/nixos/">NixOs</a>. The key part is that I need to use <code>/usr/bin/env bash</code> for all my shebangs instead of assuming the path to <code>bash</code>.</p>
<pre><code class="language-sh"># !/usr/bin/env bash
</code></pre>
<p>So that meant I needed to go into that project to fix it (and add a few features I've been wanting). But that was so old that I spent a few days bringing it up to fix my new <a href="/tags/project-layout/">project layout</a> so I had a consistent environment. While doing that, I ended up on yet another tangent to create a script that could create my script files. (Not sure where to store that, to be honest.)</p>
<p>But then I finished the script to get the layout working to get Markdown working. After another day or so to coerce <code>markdowny</code> into <a href="/tags/woodpecker-ci/">Woodpecker CI</a>, I was finally ready to actual write a feature I've been needing for a while.</p>
<h2>New Feature</h2>
<p>To submit entries to my writing group, I need to post a “events so far” document because it could be weeks or months between submissions. I use <code>markdowny</code> to do that with the <code>list</code> command:</p>
<pre><code class="language-sh">$ markdowny list chapters/*.md | head -n 5
1. Always Moving: While Linsan waits for her mother to come home, she bounces around on the furniture and talks to her father. She announces that she has named a violin her father is making Palisis and learns that the violin is for her father's first wife who got married to her mother's best friend.
2. Early Lessons: Years later, Linsan is learning how to play the violin from her father. The lesson is interrupted when Dukan, her father's best friend and manager for the business, visits in a panic to tell him that the family's workshop in the valley is on fire.
3. Home Early: Unable to visit the burnt remains of the family's workshop, Linsan comes home to find her father work in depression. He had given up working on instruments and switched to writing articles about music. She goes into the attic to put some books away and finds Palisis in a corner, returned after Marin's death. She plays it, but then finds out that no one had ever played it before.
</code></pre>
<p>I needed a bit more details, so I decided to expand it to use Handlebars to give me a template for the chapters and to access all of the components inside the YAML header.</p>
<pre><code class="language-sh">$ markdowny list ~/src/fedran/sources/allegro/chapters/*.md --template='- Chapter {{_number}} - {{{title}}} => {{{summary}}}' --trim-whitespace | head -n 5
- Chapter 1 - Always Moving => While Linsan waits for her mother to come home, she bounces around on the furniture and talks to her father. She announces that she has named a violin her father is making Palisis and learns that the violin is for her father's first wife who got married to her mother's best friend.
- Chapter 2 - Early Lessons => Years later, Linsan is learning how to play the violin from her father. The lesson is interrupted when Dukan, her father's best friend and manager for the business, visits in a panic to tell him that the family's workshop in the valley is on fire.
- Chapter 3 - Home Early => Unable to visit the burnt remains of the family's workshop, Linsan comes home to find her father work in depression. He had given up working on instruments and switched to writing articles about music. She goes into the attic to put some books away and finds Palisis in a corner, returned after Marin's death. She plays it, but then finds out that no one had ever played it before.
- Chapter 4 - Solace in Memories => As Linsan frequently did, she visited the family's ruins after school. The spot gave her peace despite everything they had lost. However, a bully from school, Dukan's daughter Brook, follows after her and they fight. During the brawl, they both manifest their powers: Linsan with music and Brook with concussion powers.
- Chapter 5 - Bitter Partings => Linsan comes limping home after her fight with Brook. Her parents are surprised she is there, but then Dukan and Brook show up. Dukan has his daughter apologizes and then offers to send money to the Sterlig's. Linsan's father tries to refuse it, but Dukan phrases it as helping Linsan and they accept.
</code></pre>
<p>It might not be much, but it was something I've been looking for. It also means that I can include things like POV, when it happened, or other details in the list to help work timelines, locations, and the like. Or use it as a simple index page generator for HTML and Gemini pages, if someone found a use for that.</p>
<h3>Tables</h3>
<p>Of course, there is also a table approach to the same thing:</p>
<pre><code class="language-sh">markdowny table chapters/*.md --fields _basename title when.start locations.primary | head -n 5
</code></pre>
<table>
<thead>
<tr>
<th style="text-align: left;">_basename</th>
<th style="text-align: left;">title</th>
<th style="text-align: left;">when.start</th>
<th style="text-align: left;">locations.primary</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">chapter-01.md</td>
<td style="text-align: left;">Rutejìmo</td>
<td style="text-align: left;">1471/3/28 MTR 4::22</td>
<td style="text-align: left;">Shimusogo Valley</td>
</tr>
<tr>
<td style="text-align: left;">chapter-02.md</td>
<td style="text-align: left;">Confession</td>
<td style="text-align: left;">1471/3/28 MTR 4::75</td>
<td style="text-align: left;">Shimusogo Valley</td>
</tr>
<tr>
<td style="text-align: left;">chapter-03.md</td>
<td style="text-align: left;">Morning</td>
<td style="text-align: left;">1471/3/28 MTR 11::71</td>
<td style="text-align: left;">Shimusogo Valley</td>
</tr>
</tbody>
</table>
<h2>Nor Curse Be Found</h2>
<p>Despite all that, I got another chapter of Nor Curse Be Found written this afternoon. It isn't polished as I hope, I'm still struggling with the “feel” for the chapter and how the prince responds to things, but that is also something I have to finish to really understand and go back to edit.</p>
<p>Overall, it was a good day (it took me three days to write the chapter).</p>
Faking Time Magic with Nitride2023-01-21T06:00:00Zhttps://d.moonfire.us/blog/2023/01/21/faking-time-magic-with-nitride/Just a little summary of how to handle time while generating sites with Nitride.
<p>It's been a while since I've talked about <a href="/tags/mfgames-nitride/">MfGames.Nitride</a> and I thought I would do a short post about working with time-sensitive posts. In most cases, this is dating blob posts but it can also be how I dole out weekly chapters while building up a buffer while I enjoy some down time.</p>
<h2>NodaTime</h2>
<p>All the time elements in Nitride use <a href="https://nodatime.org/">NodaTime</a> instead of the base class library's <code>DateTime</code>. Part of this is because it predates the advent of <code>LocalDate</code> but also because NodaTime has good abstractions around providing the time for reliable manipulations of time, an obsession with correctness, and also a deep understanding of the complexities of temporal elements.</p>
<p>None of these really matter, but I like the library and I felt it was a solid base. This is also one reason why Nitride is opinionated.</p>
<h2>Getting Started</h2>
<p>To use the temporal library, you need to include the <a href="https://src.mfgames.com/mfgames-cil/-/packages/nuget/mfgames.nitride.temporal">NuGet package</a> into your project and then either inject the module into the class or use the extension method.</p>
<pre><code class="language-csharp">NitrideBuilder builder = new NitrideBuilder(args)
.UseTemporal(
config =>
{
config
.WithDateTimeZone("America/Chicago")
.WithDateOptionCommandLineOption();
});
</code></pre>
<p>The configuration is optional, but this shows the two most common options. The first sets the time zone for all the local dates to handle when your site generates even if your server or build machine is UTC or in a different time zone.</p>
<p>The other adds a <code>--date YYYY-MM-DD</code> option to the command line to let you choose the “now” that the site is running, such as to preview next week's post or see how everything will turn out. If the <code>--date</code> is not provided or the command line option isn't used, then “now” will be now. Well, then, but it was now then, but if you run it now, then it will now. Well, then. (<a href="https://en.wikipedia.org/wiki/Spaceballs">Spaceballs</a> reference.)</p>
<pre><code class="language-shell">dotnet run -- build --date 2023-01-25
</code></pre>
<h2>The Basics</h2>
<p>Even with the module, nothing more is going to happen than additional logging line in the output. Because this is an <span class="missing-link" data-path="/tags/entity-component-system/">Entity-Component-System</span>, adding time to an <code>Entity</code> is as simple as setting the instant.</p>
<pre><code class="language-csharp">Instant instant;
var entity = new Entity().Set(instant);
</code></pre>
<p>Of course, this only applies to a single entry, so there are two operations included that will mass assign <code>Instant</code> components to entities. The first is <code>SetInstantFromComponent</code>. This gets a <code>LocalDate</code>, <code>DateTime</code>, <code>DateTimeOffset</code>, or <code>Instant</code> from the entity (<code>Model.Date</code> in this example) and returns it. If this returns a null, then no instant will be assigned.</p>
<pre><code class="language-csharp">public class Model
{
public string Access { get; set; } = "public";
public DateTime? Date { get; set; }
}
public Pipeline : PipelineBase
{
private SetInstantFromComponent<PageModel> op;
public Pipeline(
SetInstantFromComponent<PageModel> op)
{
this.op = op
.WithGetDateTimeObject(entity => entity.Get<Model>().Date);
}
public override IAsyncEnumerable<Entity> RunAsync(
IEnumerable<Entity> entities,
CancellationToken cancellationToken = default)
{
return entities
.Run(op)
.ToList()
.ToAsyncEnumerable();
}
}
</code></pre>
<p>As a basic functionality, it is pretty simple. However, the most common way I need to assign an <code>Instant</code> are my blog posts which all have the following pattern:</p>
<ul>
<li><code>./posts/2023-01-21/faking-time-magic-with-nitride/index.md</code></li>
</ul>
<p>To handle this common condition, there is a second operation: <code>SetInstantFromPath</code>.</p>
<pre><code class="language-csharp">SetInstantFromPath op;
return entities
.Run(op)
.ToList()
.ToAsyncEnumerable();
</code></pre>
<p>This one doesn't require any customization to it because it uses a regular expression with named groups to calculate the three components. This is the same as setting the regular expression:</p>
<pre><code class="language-csharp">return entities
.Run(op.WithPathRegex(@"(?<year>\d{4})[/-](?<month>\d{2})[/-](?<day>\d{2})"))
.ToList()
.ToAsyncEnumerable();
</code></pre>
<p>Obviously the default is ISO date time, but I'm not going to support anything besides that in the defaults since you can writ a custom regular expression with named groups to handle any arbitrary format. The default also handles <code>2028/01-21-faking-time-magic-with-nitride.md</code> as well as my normal format. In the end, the <code>Entity</code> has an <code>Instant</code> component.</p>
<h2>Using Instants</h2>
<p>Of course, setting an <code>Instant</code> requires it to be used somewhere. Since it is a component, it is relatively easy to get the latest X posts from a list of entities.</p>
<pre><code class="language-csharp">var latest = entities
.WhereEntity<Instant>()
.OrderByDescening(entity => entity.Get<Instant>())
.Take(x)
.ToList();
</code></pre>
<p>This is used to create feeds, but that is a topic for later since generating Atom feeds needs some more attention before I'm comfortable with it.</p>
<p>The instant can also be used to remove future instants via the creatively named <code>FilterOutFutureInstant</code> which has no configurations thank to the use of the <code>--date</code> parameter and <code>TimeService</code> in its dependency-injected constructor.</p>
<pre><code>FilterOutFutureInstant op;
return entities
.Run(op)
.ToList()
.ToAsyncEnumerable();
</code></pre>
<p>In most cases, I gather up all the pages, generate the project pages so I can show future chapters but grayed out, then remove the future ones before producing the HTML so no one can “cheat” by just adding one to the page.</p>
<h2>Schedules</h2>
<p>The above operations and concepts pretty much got me through generating <a href="//d.moonfire.us">d.moonfire.us</a>. On the other hand, <a href="//fedran.com">fedran.com</a> needed something more since I don't date my chapters. Instead, they are things like <a href="//fedran.com/sand-and-blood/chapter-01/">fedran.com/sand-and-blood/chapter-01/</a> and they need to be sent out every week until I run out of buffer or fail to keep up.</p>
<p>To support that, I added a <a href="https://src.mfgames.com/mfgames-cil/-/packages/nuget/mfgames.nitride.temporal">second NuGet package</a>, <code>MfGames.Temporal.Schedules</code> which contains more complex operations that adjust or change an entity's attributes based on the current date. In both cases, they are driven off a “path” which may be any arbitrary component but default to the entity's <a href="https://github.com/xoofx/zio">Zio.Upath</a> component. They allow me to set up a schedule in a separate YAML file (could be JSON, could be on the page) and then they change.</p>
<h3>PeriodicPathRegexSchedule</h3>
<p>The first is <code>PeriodicPathRegexSchedule</code> which is the initial evolution of writing a schedule for static sites. It uses a regular expression to capture the numeric part of a path (<code>12</code> from <code>chapter-12</code>) and figure out how long to show it. If we use the <code>Model.Access</code> above to control access, we can easily make chapters available for subscribers and then spread them out a week at a time starting at the beginning of the year.</p>
<pre><code class="language-yaml">schedules:
# Patron and Ko-Fi subscribers get it all at once
- pathRegex: chapters/chapter-(\d+)
scheduleStart: 2000-01-01
schedulePeriod: instant
access: subscribers
- pathRegex: chapters/chapter-(\d+)
scheduleStart: 2023-01-01
schedulePeriod: 1 week
access: public
</code></pre>
<p>Depending on the “now” when the site is run, all the chapters are available to patrons but they will be made public at the rate of one per week starting with the first chapter on January 1st. Of course, with regular expressions, I could easily stop posting chapters for a while by splitting the regular expression in two to cover two ranges. Or I can have two schedules that have a tier-1 and a tier-2 release with a public release a week after tier-2 gets it.</p>
<pre><code class="language-yaml">schedules:
- pathRegex: chapters/chapter-(\d+)
scheduleStart: 2000-01-01
schedulePeriod: tier-1
access: subscribers
- pathRegex: chapters/chapter-(\d+)
scheduleStart: 2023-01-01
schedulePeriod: 1 week
access: tier-2
- pathRegex: chapters/chapter-(\d+)
scheduleStart: 2023-01-08
schedulePeriod: 1 week
access: public
</code></pre>
<p>This can also get complicated when I had to take breaks from chapters:</p>
<pre><code class="language-yaml">schedules:
# Patron and Ko-Fi subscribers get it all at once
- pathRegex: chapters/chapter-([0-1]\d|2[0-4])
scheduleStart: 2000-01-01
schedulePeriod: 2 weeks
access: public
- pathRegex: chapters/chapter-(2[5-9]|[3-9]\d)
scheduleStart: 2023-01-01
schedulePeriod: 2 weeks
access: public
</code></pre>
<p>Obviously, implementing this is more complicated then setting the instant from the path.</p>
<pre><code class="language-csharp">public class PageSchedule : NumericalPathSchedule
{
public Access { get; set; }
protected override Entity Apply(Entity entity, int number, Instant instant)
{
var model = entity.Get<Model>();
model.Access = this.Access;
return entity.Set(instant, model);
}
}
List<PageSchedule> schedules;
Ienumerable<Entity> entities;
return applySchedules.WithSchedules(_ => schedules).Run(entities);
</code></pre>
<h3>IndexedPathRegexSchedule</h3>
<p>The second method for schedules is <code>IndexedPathRegexSchedule</code>. This is the most complicated to set up in C# code, but I find the easiest to comprehend in the YAML code. Instead of having a complex set of schedules and multiple regular expressions, it goes with a single regular expression to identify the numerical component and then has a dictionary of elements that say “from chapters X until the next, for chapters Y and later, do this, etc.”</p>
<pre><code class="language-yaml">schedules:
pathRegex: chapters/chapter-(\d+)
indexes:
1:
scheduleStart: 2025-01-01
schedulePeriod: instant # means all the chapters 1-10 at once
access: subscribers
10:
scheduleStart: 2030-01-01 # chapter 10 on 2030-01-01, chapter 11 on 2023-01-08, etc.
schedulePeriod: 1 week
access: subscribers
30:
schedulePeriod: never # never going to see these
</code></pre>
<p>This one works easier for me, mainly because Fedran doesn't have subscriber tiers or complex logic but I do have frequent pauses while posting. Also, the schedule isn't an outer list (though it could be, <code>ApplySchedules</code> applies every schedule in order so you can have two of these without a problem).</p>
<pre><code class="language-csharp">public class Schedule : IndexedSchedule
{
public string? Access { get; set; }
protected override Entity Apply(
Entity entity,
int number,
Instant instant)
{
TestModel model = entity.Get<TestModel>();
model.Access = this.Access;
return entity.SetAll(instant, model);
}
}
IndexedPathRegexSchedule<Schedule> schedules;
Ienumerable<Entity> entities;
return applySchedules.WithSchedules(_ => new [] { schedules }).Run(entities);
</code></pre>
<h2>Conclusion</h2>
<p>As you may notice, these don't filter out or do anything other than set the <code>Instant</code> and maybe some other components of an <code>Entity</code>. This follows the Single Responsibility Principle (SRP) but also “do one thing well”. If you want to filter it out, use an operation for that. If you want to dynamically change the contents of a page based on the current day, that's a schedule.</p>
<p>This is also a starting point. Everything is fluid. I have thirteen websites I'm planning on converting over to Nitride over the next year or so. The fourth site is mfgames.com when I'll start documenting all of this and probably start pushing to see if others want to use it. Right now, the only documentation comes from <a href="https://src.mfgames.com/mfgames-cil/">https://src.mfgames.com/mfgames-cil/</a> in the examples, read me files, and tests.</p>
Migrating to Take Away the Pain2022-09-06T05:00:00Zhttps://d.moonfire.us/blog/2022/09/06/migrating-to-take-away-the-pain/I had surgery last Friday. It was and continues to be painful, so I needed to distract myself so I decided to finish up the process of migrating my C# projects from GitLab over to my Gitea instance.
<p>I had surgery last Friday. It was and continues to be painful, so I needed to distract myself so I decided to finish up the process of migrating my C# projects from <a href="/tags/gitlab/">GitLab</a> over to my <a href="/tags/gitea/">Gitea</a>: <a href="https://src.mfgames.com/mfgames-cil/">https://src.mfgames.com/mfgames-cil/</a>.</p>
<p>At this point, all of my libraries had been moved over, CI changed over to <a href="/tags/woodpecker-ci/">Woodpecker CI</a> and deploying to the NuGet repository on the Gitea server. I also went through each of them and set up source mapping which means all of the “MfGames.*” will only point to my host and everything else will go to nuget.org as normal.</p>
<pre><code class="language-xml"><?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="mfgames.com" value="https://src.mfgames.com/api/packages/mfgames-cil/nuget/index.json" protocolVersion="3" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="mfgames.com">
<package pattern="MfGames.*" />
</packageSource>
</packageSourceMapping>
</configuration>
</code></pre>
<p>There is still a lot more to do in process, but I feel good about having things over on my own system. I did love GitLab a lot, they have taken care of me for many years, they just went in a direction I can't follow.</p>
<p>In specific, they made everything free and open in the beginning, but as they got success, they needed to start to make a profit. That's understandable, but I was unable to find a reasonable way of affording such services and their sales stopped talking to me when they saw how small I was (I have many organizations but but with only 1-2 users and they couldn't tell me how to send them money to allow that). So, my $20/month goes into hosting my instances instead.</p>
<p>Most of the <a href="/tags/fedran/">Fedran</a> sources are already migrated, but they are not hooked up to Woodpecker CI so I don't really consider them “migrated”. Also, Woodpecker doesn't have a scheduled post so I can't do my daily update that I use pretty heavily so the websites haven't migrated.</p>
<p>This also ties into my short-term plan over the next few months, so once I get this site (<a href="https://d.moonfire.us/">https://d.moonfire.us/</a>) migrated, then I can start pushing to get fedran.com ready to host <a href="/tags/flight-of-the-scions/">Flight of the Scions</a> for November 8th.</p>
Semantic Release and Woodpecker CI2022-08-07T05:00:00Zhttps://d.moonfire.us/blog/2022/08/07/semantic-release-and-woodpecker-ci/In my migration from GitLab to Gitea, I've started moving my CI/CD server over to Woodpecker. Here is some of the struggles I've done through in the process of getting it to work.
<p>With the recent drama of <a href="/tags/gitlab/">GitLab</a>, both with the CI/CD changes and then more recent possible threat of deleting old repositories, I continue my migration to a local <a href="/tags/gitea/">Gitea</a> instance, <a href="https://src.mfgames.com/">https://src.mfgames.com/</a> for the bulk of my code and writing.</p>
<p>For the most part, migrating is just a matter of shuffling data. I have a <em>lot</em> of repositories, both active and inactive, and it will take me months to move them over. Plus I haven't decided if I'm going to purge them from my GitLab account so there is a single source of truth or just mirror back to them.</p>
<p>Currently, the most difficult task was figuring out how to handle the build processing. I've mentioned previously that I use <a href="/tags/conventional-commits/">Conventional Commits</a> and <a href="/tags/semantic-release/">Semantic Release</a> fairly heavily. I've branched out a little from there using <a href="/tags/lefthook/">Lefthook</a> and my <a href="/garden/project-layout/">project layout</a>.</p>
<p>Currently, the CI does the following:</p>
<ol>
<li>Build the project</li>
<li>Test various conditions including valid commit messages</li>
<li>If the commits indicate a new build:
<ol>
<li>Tag it</li>
<li>Build the release version</li>
<li>Create a release on Gitea</li>
</ol>
</li>
</ol>
<p>This changes over time, but it is the basic pattern.</p>
<h1>Tags and Git Depth</h1>
<p>Woodpecker does not automatically download the needed tags for <code>semantic-release</code> (and <a href="/tags/gitversion/">GitVersion</a>). This means that the <code>.woodpecker.yml</code> file needs to include tags.</p>
<pre><code class="language-yaml">clone:
git:
image: woodpeckerci/plugin-git
settings:
tags: true
pipeline:
# The pipeline elements
</code></pre>
<p>Unike GitLab, which only limits to the last ten commits, it appears that Woodpecker <a href="https://woodpecker-ci.org/plugins/plugin-git">downloads the full repository</a> by default which is also needed by GitVersion because it calculates every version. Not entirely sure about <code>semantic-release</code> logging indicates it doesn't need the full repository, just enough back to find a version.</p>
<h1>Building and Testing</h1>
<p>To support task branches, I have a basic build and test code that runs on pushes and pull requests. This lets me identify bugs earlier and catch typos with my commits.</p>
<pre><code class="language-yaml">build:
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
commands:
- nix develop --command scripts/build.sh
when:
# We need both "tag" for the next section.
event: [push, pull_request, tag]
tag: v*
test:
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
commands:
- nix develop --command scripts/test.sh
when:
event: [push, pull_request]
</code></pre>
<p>From the build tasks, you can see that I'm using my current project layout which uses scripts in the <code>scripts/</code> folder instead of <code>npm run</code> or <code>dotnet run</code>. This is to make it easier to work with polyglot plus works around the issue that I need to use <code>nix develop</code> to get into my reproducible environment since the Docker image doesn't automatically do that. This is because both Gitlab and Woodpecker use the image which bypasses initialization files and I couldn't have it run <code>direnv allow</code> automatically to set up environment variables.</p>
<p>One thing that is missing is that Woodpecker doesn't have a clean mechanism for temporary build artifacts. I can't upload the build files and then download them so I can see the final results. Instead, I have to script it out or use a S3 plugin.</p>
<h1>Building on Versions</h1>
<p>With most cases, I build the release version of the project when the conventional commits indicate that there is a new version (<code>feat</code> and <code>fix</code>). This is an additional pipeline that comes after the <code>test:</code> line.</p>
<pre><code class="language-yaml">release-main:
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
commands:
- export DRONE="true" # Required to convince `env-ci`
# semantic-release needs this locally
- git branch $DRONE_BRANCH origin/$DRONE_BRANCH
- nix develop --command scripts/release.sh
secrets:
- gitea_token
- git_credentials
when:
event: push
branch: main
</code></pre>
<p>There are a number of things in this block that took me a while. The first is the <code>event</code> and <code>branch</code>. We only do releases on the <code>main</code> (I'm still moving away from <code>master</code> as racist language).</p>
<p>The second is the <code>export DRONE</code> line. At the time I set this up, <a href="https://www.npmjs.com/package/env-ci">env-ci</a> wasn't aware of Woodpecker, but it was <a href="https://github.com/woodpecker-ci/woodpecker/pull/1035">recently added</a> thanks to 6543 on the Woodpecker Matrix channel, <code>#woodpecker-ci:matrix.org</code>. I don't know when the latest <code>semantic-release</code> will have it, but it shouldn't be needed soon, if not already.</p>
<p>The third is the <code>git branch</code> line in the above script. Woodpecker creates a detached head, as does Gitlab. But when it doesn't do is also create a local branch for the one being created. This causes a problem because the release process appears to “jump” to the branch to figure out the changes between the detached head (the commit being built) and the actual branch.</p>
<p>Finally, we have the secrets. <code>semantic-release</code> automatically picks up $GITEA_TOKEN for the release process but also needs $GIT_CREDENTIALS to verify Git access.</p>
<p>The token is easy, that is what given by Gitea for the user.</p>
<p><a href="https://github.com/semantic-release/semantic-release/blob/master/docs/usage/ci-configuration.md">GIT_CREDENTIALS</a> is slightly harder, it is a colon-separate tuple of the user name and the Gitea access token. From observations, the Gitea is basically just a bunch of URL-safe characters, so the URL-escaping isn't needed in my case (you need to URL-escape the left and right of the colon but not the colon itself).</p>
<pre><code class="language-shell">$ export GITEA_TOKEN=9fc6d72c72e4b149f07491a0b2d3ec9215d57caf
$ export GIT_CREDENTIALS="dmoonfire:$GITEA_TOKEN"
</code></pre>
<p>These need to be set on a per-project basis since Woodpecker, unlike GitLab and <a href="/tags/sourcehut/">sourcehut</a>, there doesn't appear to be a good way of having a shared set of secrets for projects (GitLab has organization/group level secrets, sourcehut has the secret storage). This means I have to set the same GITEA_TOKEN and GIT_CREDENTIALS for all 80+ of my <a href="/tags/fedran/">Fedran</a> repositories†.</p>
<p>† Woodpecker has a CLI, <code>woodpecker-cli</code> which will let me automate that. I will use that.</p>
<h1>Create Release on Tag</h1>
<p>One thing I'm moving toward is creating a release entry on the forge. Since this happens after the build process and Woodpecker uses a different Docker image, I need it to be a post-release event so I hang it off the tagging process instead of the push to <code>main</code>.</p>
<p>6543 came to my rescue again with this one, so that is why there are those two “tag” elements in the script above. I also have a new stanza for the release process:</p>
<pre><code class="language-yaml">release-gitea:
image: plugins/gitea-release
settings:
base_url: https://src.mfgames.com
files:
- "*.pdf"
- "*.epub"
api_key:
from_secret: gitea_token
when:
event: tag
tag: v*
</code></pre>
<p>If I didn't have the <code>event:</code> and <code>tag:</code> in the <code>build:</code> stanza, it wasn't working for the tags. This caused me some difficulties because I usually treat hashes as being unordered, but Woodpecker uses file order for processing pipelines. So, I needed to have the <code>build:</code> target build the file (with the correct version because it was tagged) and then <code>release-gitea:</code> to use that output for the release process. The <code>test:</code> and <code>release-main:</code> are skipped because they don't have those events listed.</p>
<p>In addition, secrets are handled differently when done as a parameter for a plugin. That is why I have the <code>from_secret:</code> element in the above script. This inconsistency threw me for a few days.</p>
<h1>Putting it Together</h1>
<p>If you want to see the final version, check out <a href="https://src.mfgames.com/dmoonfire-garden/project-layout/src/branch/main/.woodpecker.yml">this example</a> which has my current version as a single file.</p>
<h1>Conclusion</h1>
<p>I'm happy to move over to Woodpecker (you know, except for the cost of hosting) both because of the control and the challenge. I also don't have a need for speed, so if it takes a while to get through the queue, I'm okay.</p>
fedran-cli2022-01-16T06:00:00Zhttps://d.moonfire.us/blog/2022/01/16/fedran-cli/I started working on a small tool, `fedran-cli`, to help me manage and work with the growing cluster of stories and novel Git repositories and automated processes.
<p>Due to some random happenstance, I was presented the opportunity to get a sensitivity reader for <a href="/tags/flight-of-the-scions/">Flight of the Scions</a>. I've been thinking about doing this for a few years, ever since I realized I rewrote the novel for no-so-great reasons but had the misfortune of hanging much of the phase-1 stories off of events in that book.</p>
<p>This forced me to integrate the edits I've been avoiding for the last six months and get them into the site. So, the version currently on my website would be the latest, but at the moment, there is a bug preventing me from actually showing them.</p>
<p>I know that <em>Flight</em> has been hanging around for decades (it was supposed to be my first published novel) but this is a step that I've been feeling like I need to do. Of course, my anxiety helpfully suggests that the reader is going to find the novel complete and utter trash so there is that. I'm hoping it isn't but I've never had a sensitivity reader before and I'm not sure what to expect.</p>
<p>To distract myself from the impending complete rejection of my project, I needed to distract myself. I have a writing commission that I needed to finish, but that was limited to off-hours because of the concentration required and I couldn't do it with the kids.</p>
<p>To do something, and hopefully get a dopamine hit, I dug up a project that I had started a few times but failed: a program to help me work with my <a href="/tags/fedran/">Fedran</a> projects. In specific, something that would let me update and add <a href="https://fedran.com/sources/">characters and volumes sources</a> easily.</p>
<p>Along the way, I figured I'd include a few other items that have been bothering me. One of the biggest, which is needed for the fedran.com rewrite was to be able to check out the Git repositories in a single shot. That requires me to identify my stories, which is going to get more complicated since I recently (last year) decided that I was going to be purely one repository per story to handle versioning better.</p>
<p>According to my sources page, I have exactly eighty stories and novels. That means I need a central place to keep track of eighty repositories. I could maintain them in the website folder, but I thought tying it into my <code>identifiers.json</code> (formerly YAML) would be a good way of centralizing all the information about the sources in a single place.</p>
<p>Hence, I'm working on <code>fedran-cli</code> which is a CLI for working with the Fedran ecosystem. Since I recently started playing with <a href="/tags/nix/">Nix</a>, I wanted to figure out a way of integrating <code>fedran-cli</code> into that whole mess without me needing to do some formal release process. Originally, I tried a <span class="missing-link" data-path="/tags/csharp/">C#</span> version because I can't get C# to play with my new libraries in Nix. However, I could make it work in <a href="/tags/rust/">Rust</a> so I banged up a basic program that lets me choose the existing character and volume for a given project.</p>
<p>(I was going to upload a GIF to this post, but I helpfully used the <code>rm</code> command instead of <code>mv</code>, so here is a <a href="https://octodon.social/@dmoonfire/107616954866735580">link to the post with a video including alt text</a> on my social page).</p>
<p>For a non-trivial Rust application, I was pretty happy with the results. I have a number of other commands I need to write for basic functionality and what I consider minimum viable product.</p>
<ul>
<li><code>fedran-cli characters add</code> to add new characters.</li>
<li><code>fedran-cli volumes add</code> to add new volumes.</li>
<li><code>fedran-cli project sync</code> to upload a subset of information to the identifiers file including the Git repository.</li>
<li><code>fedran-cli git clone --all</code> to basically clone the eighty sources into the current directory based on the identifier file.</li>
</ul>
<p>This is kind of an untethered project for me. The CLI doesn't really have an end, just an “end for now”. But, I think if I focus on getting to the <code>git clone --all</code>, I should have something that can help me.</p>
The End After Three Hundred Weeks2021-03-17T05:00:00Zhttps://d.moonfire.us/blog/2021/03/17/three-hundred-weeks/Six years ago, I started posting weekly chapters. As of this week, I have been doing that for three hundred consecutive weeks. It is also time for me to stop.
<p>Just under two years ago, I posted about how I had been posting weekly chapters for <a href="/blog/2019/04/19/two-hundred-weeks/">two hundred consecutive weeks</a>. Since then, I've managed to do it for another hundred weeks which puts me up to six years of posting (mostly) consistently. There were two instances where I missed a week but I caught up and returned quickly. Overall, I can say three hundred weeks of posting with a straight face and still feel like I wasn't lying.</p>
<p>I had a lot of hopes in 2019. Things were looking positive and I was writing strong. I found a new community and they were throwing thumbs up at me. Then 2020 hit and things started to get a little less rosy. I don't need to say what happened, but my household has been in relative isolation since March and then we got hit by the derecho in August. They still haven't finished fixing the roof or repairing the hole in the side of my house before the snow came.</p>
<p>(Unlike my normal rule of limiting negative posts, this one talks about depression.)</p>
<h1>Skill and Perceptions</h1>
<p>Somewhere in September, I started to get a feeling that everything I was writing was “wrong”. I can't tell how it was wrong, only that I wasn't capable of fixing it because I couldn't tell what I was missing. It didn't take long to realized was in a slump probably related to the skill/perception curve (<a href="https://auriee.tumblr.com/post/139955231381/how-to-improve-understanding-knowledge-skill">source</a>).</p>
<p><img src="./skill-perception.jpg" height="256" style="margin-top:1em;" alt="Skill/Perception Curve" /></p>
<p>I'm just left of frowning face, a point where I know something is wrong but my skills and abilities aren't enough to identify the problem. I've had this feeling before, where I know there is something wrong, but I've never had a situation where I had no clue how to improve my writing.</p>
<p>This discomfort with my writing continued to grow, sapping my creativity.</p>
<h1>Flight of the Scions</h1>
<p>In October 2020, I also had <a href="https://fedran.com/flight-of-the-scions/">Flight of the Scions</a> edited. When I didn't get the enthusiasm I was hoping for the piece, that pretty much sent me down a spiral and the growing sense that I was missing something turned into a full-blown loathing. I haven't integrated the edits for that novel because of it… because I feel like I can never do the piece justice.</p>
<h1>Plague</h1>
<p>In November, I got sick.</p>
<h1>End of the Year</h1>
<p>In mid-December, I still wasn't able to identify what was wrong with my writing. I was writing. I was still passionate about <a href="https://fedran.com/allegro/">Allegro</a> but every word that got down on the page felt alien, twisted and foul.</p>
<p>That was also the point I realized that I can't just push myself past it. There weren't enough words because I just spent months not liking my words but unable to find the epiphany that would help me through the roadblock.</p>
<h1>NaNoWriMo</h1>
<p>Something has to change if I want to keep getting better at my writing. I've written a lot, I've grown as a writer and as a person. More importantly, I want to graduate from an “okay” writer to a “good” writer. This requires me to figure out what I'm missing.</p>
<p>While I thought about it, I looked at what writing weekly was giving me. At the beginning, much like <a href="https://en.wikipedia.org/wiki/National_Novel_Writing_Month">NaNoWriMo</a>, it was about “can I do it”. Six years of writing says I can. I also will admit, my writing has significantly improved in the six years of steady writing and I'm a much stronger creator than ever.</p>
<p>But I don't think I've improved much in the last year. I think I have reached the top of this mesa with my skill by just forcing out more words. I need something more deliberate, which also means less grinding out words and more of trying things to shuffle things up and expand in a new direction.</p>
<p>I said the same thing about NaNoWriMo. I was able to do it, but the month of writing wasn't really the challenge. For me, it was more about getting the word count, but I already know I can write fifty thousand words in four days. I've done it, more than once. I even published the results of one of those experiences.</p>
<p>NaNoWriMo came down to word count, which is a metric that I love to use but it also a useless one for me. It slides under the <a href="https://en.wikipedia.org/wiki/Goodhart%27s_law">Goodhart's Law</a>:</p>
<blockquote>
<p>When a measure becomes a target, it ceases to be a good measure.</p>
</blockquote>
<p>Word counts, including minimum words a day or reaching a certain number, isn't helping me because I just work toward the target. With NaNoWriMo, I find that I can't easily write past 50k words even if the story needs it. A word count in a day becomes a chore.</p>
<p>Same with writing time.</p>
<p>Using likes and reviews is also difficult because I'm an okay writer, not a good one. The volume of what I write means folks stop reading it, or they realize I'm not a good writer. I'm not sure without feedback, so I'm going to say they don't work because I can't measure anything.</p>
<h1>Burnout</h1>
<p>To be honest, much of this feels like burnout also. I've gone through two major burnouts in my life and I think the weekly chapters are beginning to strip those screws bare again. That just gives more credence to the idea of stopping my weekly chapters.</p>
<p>Burnout also leads to depression and a feeling of worthlessness that never goes away. That's been hanging around me since I was seventeen but it got really bad since August. Every time I stumbled into the “never write out of your lane,” I realized I had created a world that would require me to venture out and I shouldn't have. Every time I got a rejection, I knew I wasn't that good of a writer. Every time I tried to convince someone to read my work and they just… gave up, it just reinforced that.</p>
<p>So the logical response, to avoid upsetting everyone, was to consider giving up. Not because of a “if I can't write that, then I should stop writing” but more of a realization that I'm not really that important and there are far better people out there that need the space more than me.</p>
<p>I've been struggling with this for months. I think one of the reasons I have have only made a single submission in the last four years is because of that. (I was rejected, of course.) There are “own voices” that need to be said more than what I do. I can't do much beyond boosting others, but not trying to draw attention to myself is one of those. This is something I've been considering for months.</p>
<p>Because of that, I'm having trouble wanting to draw attention to myself. My weekly chapters were a single post around six in the morning once a week and I consider that excessive. When I finished my last book, it was a second posting in a week and nothing more. I don't know if I can, or want, to go beyond that. I haven't asked for a table at ICON for the same reason. I haven't paid for advertisement either.</p>
<h1>Mr. Tanner</h1>
<p>I'm not going to stop writing. I don't think I can stop writing. It brings me so much joy and I love creating stories. I just don't know who I'm writing for anymore. In many ways, the final lyrics of Harry Chaplin's “<a href="https://www.youtube.com/watch?v=upZB5VlbC6o">Mr. Tanner</a>” have been speaking to me.</p>
<blockquote>
<p>Music was his life, it was not his livelihood<br />
And it made him feel so happy and it made him feel so good<br />
And he sang from his heart and he sang from his soul<br />
He did not know how well he sang; It just made him whole</p>
</blockquote>
<p>Much like James White's <a href="https://www.sectorgeneral.com/shortstories/fasttrip.html">Fast Trip</a>, “Mr. Tanner” has become a sign of the last year or so.</p>
<h1>What's Next</h1>
<p>I don't know.</p>
<p>Right now, I'm focusing on finishing projects and not writing anything new. That includes a side piece, <em>Flight of the Scions</em> (hopefully for August), and <a href="https://fedran.com/second-hand-dresses/">Second-Hand Dresses</a> for November.</p>
<p>If I do write something new, I want to finish <em>Allegro</em> because I'm almost near the end. I also had a vague idea of sending it to the inspiration of the novel, but then I made Linsan a demisexual with lesbian tendencies and I probably overstepped my bounds. I will release the chapters for public reading as I go because I started that way and I feel that is a social contract I'm not willing to</p>
<p>I honestly don't know about new stories or novels. I like the occasional up-vote on various channels. To be honest, very few folks are actually reading it. When they do, it's in a surge and then they wander off. I have two fans on Patron but only one speaks up; I can't thank either of them enough for the encouragement.</p>
<p>If this is burnout, then I need time to recover. I need adventures and to work on other things.</p>
<p>There is always a fear that I just started the process of giving up on writing, but I can't honestly tell at this moment. It's possible, but that is life. It changes, it evolves. I've been writing fiction, in some form, for at least forty years. I can't imagine just stopping cold, but then again, I wasn't planning on getting married, having children, and having a hole punched in the side of my house.</p>
World-Building - Tarsan2020-01-29T06:00:00Zhttps://d.moonfire.us/blog/2020/01/29/tarsan/Tarsan is one of the most significant countries in Fedran, as both the oldest established country at the time of the Mechanical War and its influence on the rest of society.
<p>Tarsan is a country located in the north-western coastal region of the continent. It borders directly against Gepaul.</p>
<p>Despite being a relatively small country, Tarsan has provided significant influence over civilization in the northern and western parts of the continent. Much of this comes from Tarsan's history as the oldest, established country on the continent.</p>
<h1>History</h1>
<h2>Countless Hills</h2>
<p>Before Tarsan was established, much of the region was known as the Countless Hills. The hills were claimed by various feuding families, clans, and tribes. Alliances were formed and broken fluidly and it was a harsh The alliances and opposition were fluid during this time with betrayal common as were short-lived treaties.</p>
<p>When Jolia invaded in 436 TSC, there was almost no organized resistance or armies capable of working together enough to defeat the invaders. The southern-most families quickly fell, either by subjugation or destruction, and it quickly looked like the entire Hills region would be conquered within a few years.</p>
<p>It wasn't until a wintry morning 19.0.437 TSC that eight families along the northern coast gathered together in what would be the first Council of Tarsan. The Kasin family was the one who made deals and treaties to make this possible since most of these families had been fighting only recently with each other. Together, these families decided to set aside their differences to fight off the invaders. Much of the following days were spent in planning to take on the initial wave of invaders.</p>
<ul>
<li>Disrobin</li>
<li>Galadir</li>
<li>Joknig</li>
<li>Kasin</li>
<li>Lamaster</li>
<li>Pun</li>
<li>Rinfir</li>
<li>Wilim</li>
</ul>
<p>However, what the Galadir family didn't know was that the other seven families were setting them up to be sacrificed as a decoy. During the first major battle, the Battle of Magdaleon, the betrayal was complete and the Galadir family was completely destroyed to give the other seven families a chance to flank and destroy the battalion of invaders.</p>
<p>Encouraged by their success, the newly formed Army of Tarsan, as it would be known, cut through the supply lines of two other Jolia battalions and began to a guerrilla attack against the invaders. These moving battles would last for close to eleven months years until the Battle of Polenus when Tarsan was able to completely cut off the Jolia invaders and collapse the Polenus Pass, the primary route from Jolia into the Countless Hills.</p>
<p>In the first battle with the invaders, the other seven families sacrificed the Galadir family in a battle that caused the complete destruction of the Galadirs and allowed the other armies to flank the invaders and defeat the first wave of invaders.</p>
<h2>Early Years</h2>
<p>After the army finished defeating the invaders, the seven families sat down at the Council of Tarsan to formally break apart. However, five of the families (excluding Pun and Joknig) decided that being banded together had given them almost complete control over the Countless Hills. The remaining two families were given an ultimatum, either permanently join into the newly formed country of Tarsan or be destroyed. They both formally accepted.</p>
<p>Using their military might, Tarsan turned their attention to the other surviving families, tribes, and clans. Even with superior force, it took them until 440 TSC until they had control over the region.</p>
<h2>Council of Tarsan</h2>
<p>Starting 0.0.441 TSC, it became a tradition that the Council of Tarsan would meet first week of the year. They would rotate the founding family that would host the council. After the somber affair of the council, the host family would then arrange celebrations throughout the city to honor Tarsan. These celebrations, over the next thousand years, would become formalized into what is now known as the Tarsan Social Season.</p>
<h1>Families</h1>
<p>Tarsan politics are organized by families, with the seven great families at the top of society and various branches and lesser families branching out through various relationships of blood and marriage.</p>
<p>Most families are patriarchal, with the eldest male becoming the head of the family. Only when there are no living males in the eldest generation will a female become head of the family. In the seven great families, they will skip a generation to avoid a female head.</p>
<p>In addition to the founding families, there are also a slew of lesser families that were either joined, subjugated, or created over the years that would follow.</p>
<ul>
<li>Pinnir</li>
<li>Tibirim</li>
<li>Xahos</li>
</ul>
<h1>Culture</h1>
<p>Tarsan culture is ritualistic from the highest ranking society members to the lowest indentured servant. The way of addressing each other, the times of day to perform various actions, and even the social calendar are all dictated by the patriarchs of the seven great families, as it has been for centuries.</p>
<h1>Timelines</h1>
<ul>
<li>0.0.436 TSC: Jolia invasion of the Countless Hills</li>
<li>19.6.436 TSC: The first Council of Tarsan</li>
<li>41.0.437 TSC: The Battle of Magdaleon</li>
<li>27.4.438 TSC: The Battle of Polenus</li>
<li>46.4.438 TSC: Establishment of Tarsan</li>
<li>35.6.440 TSC: Tarsan controls the Countless Hills</li>
<li>0.0.441 TSC: The first regular Council of Tarsan</li>
</ul>
Lexember 31 - Hissan - relif2019-12-31T06:00:00Zhttps://d.moonfire.us/blog/2019/12/31/lexember/On Lexember 31, 2019, I present "relif" as "to celebrate surviving a difficulty."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 31: relif</h1>
<h2>Pronunciation</h2>
<ul>
<li>/rɛl.ɪf/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To celebrate surviving a difficulty.</li>
<li>To survive a suicide attempt.</li>
</ol>
Lexember 30 - Hissan - egys2019-12-30T06:00:00Zhttps://d.moonfire.us/blog/2019/12/30/lexember/On Lexember 30, 2019, I present "egys" as "to celebrate families coming together."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 30: egys</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ɛ.gaɪs/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To celebrate families coming together.</li>
<li>To excitedly greet a friend after a long time apart.</li>
<li>To experience the first rush of power when returning to a home land.</li>
</ol>
Lexember 29 - Hissan - astar2019-12-29T06:00:00Zhttps://d.moonfire.us/blog/2019/12/29/lexember/On Lexember 29, 2019, I present "astar" as "to tap the energy of the land for a ritual."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 29: astar</h1>
<h2>Pronunciation</h2>
<ul>
<li>/æs.tɑːr/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To tap the energy of the land for a ritual.</li>
<li>To experience dreams while sleeping.</li>
<li>To use a term of affection for a spouse.</li>
</ol>
Lexember 28 - Hissan - tunas2019-12-28T06:00:00Zhttps://d.moonfire.us/blog/2019/12/28/lexember/On Lexember 28, 2019, I present "tunas" as "to tap a land for magic to build things."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 28: tunas</h1>
<h2>Pronunciation</h2>
<ul>
<li>/tjuːn.æs/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To tap a land for magic to build things.</li>
<li>To spend months preparing to create something.</li>
<li>To daydream.</li>
</ol>
Lexember 27 - Hissan - foosga2019-12-27T06:00:00Zhttps://d.moonfire.us/blog/2019/12/27/lexember/On Lexember 27, 2019, I present "foosga" as "to tap a land for defensive magic."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 27: foosga</h1>
<h2>Pronunciation</h2>
<ul>
<li>/fuːs.gæ/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To tap a land for defensive magic.</li>
<li>To prepare for a fight.</li>
<li>To steel oneself for an argument.</li>
</ol>
Lexember 26 - Hissan - lorkku2019-12-26T06:00:00Zhttps://d.moonfire.us/blog/2019/12/26/lexember/On Lexember 26, 2019, I present "lorkku" as "lands that border against another country."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 26: lorkku</h1>
<h2>Pronunciation</h2>
<ul>
<li>/loʊrk.kuː/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>Lands that border against another country.</li>
<li>Underwear, in specific around the groin.</li>
</ol>
Lexember 25 - Hissan - bloom2019-12-25T06:00:00Zhttps://d.moonfire.us/blog/2019/12/25/lexember/On Lexember 25, 2019, I present "bloom" as "a blood or lineage claim."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 25: bloom</h1>
<h2>Pronunciation</h2>
<ul>
<li>/bluːm/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A blood or lineage claim.</li>
<li>(Archaic) To establish a tradition.</li>
<li>To father a child.</li>
</ol>
Lexember 24 - Hissan - gyusplas2019-12-24T06:00:00Zhttps://d.moonfire.us/blog/2019/12/24/lexember/On Lexember 24, 2019, I present "gyusplas" as "to make a claim on a land."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 24: gyusplas</h1>
<h2>Pronunciation</h2>
<ul>
<li>/goʊs.plɑːs/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To make a claim on a land.</li>
<li>To attract a lover with impressive feats.</li>
<li>To sign a contract.</li>
</ol>
Lexember 23 - Hissan - gubbaba2019-12-23T06:00:00Zhttps://d.moonfire.us/blog/2019/12/23/lexember/On Lexember 23, 2019, I present "gubbaba" as "a moot baby."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 23: gubbaba</h1>
<h2>Pronunciation</h2>
<ul>
<li>/gʌb.bɑː.bæ/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A moot baby.</li>
<li>A child with an unknown father.</li>
<li>An orgy.</li>
</ol>
Lexember 22 - Hissan - ogumma2019-12-22T06:00:00Zhttps://d.moonfire.us/blog/2019/12/22/lexember/On Lexember 22, 2019, I present "ogumma" as "to leave a mother's clan."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 22: ogumma</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ɒ.gʌn.mɑː/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To leave a mother's clan.</li>
<li>To swear off using magic.</li>
</ol>
Lexember 21 - Hissan - pilmsunnad2019-12-21T06:00:00Zhttps://d.moonfire.us/blog/2019/12/21/lexember/On Lexember 21, 2019, I present "pilmsunnad" as "to negotiate a land claim."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 21: pilmsunnad</h1>
<h2>Pronunciation</h2>
<ul>
<li>/plɪm.sʌn.næd/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To negotiate a land claim.</li>
<li>To get consent for sex.</li>
</ol>
Lexember 20 - Hissan - eestor2019-12-20T06:00:00Zhttps://d.moonfire.us/blog/2019/12/20/lexember/On Lexember 20, 2019, I present "eestor" as "someone who taps a land's energy without consent."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 20: eestor</h1>
<h2>Pronunciation</h2>
<ul>
<li>/iː.stɔːr/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>Someone who taps a land's energy without consent.</li>
<li>A thief or robber.</li>
<li>A man who causes a woman to leave her family for him.</li>
</ol>
Lexember 19 - Hissan - meraslan2019-12-19T06:00:00Zhttps://d.moonfire.us/blog/2019/12/19/lexember/On Lexember 19, 2019, I present "meraslan" as "a tragedy that splits a tribe apart."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 19: meraslan</h1>
<h2>Pronunciation</h2>
<ul>
<li>/mɛr.æs.ljɑːn/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A tragedy that splits a tribe apart.</li>
<li>A land that no longer supports plant life.</li>
</ol>
Lexember 18 - Hissan - dissago2019-12-18T06:00:00Zhttps://d.moonfire.us/blog/2019/12/18/lexember/On Lexember 18, 2019, I present "dissago" as "an argument that splits a tribe apart."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 18: dissago</h1>
<h2>Pronunciation</h2>
<ul>
<li>/daɪs.sjɑː.ɡoʊ/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>An argument that splits a tribe apart.</li>
<li>An explosion caused by magical feedback.</li>
</ol>
Lexember 17 - Hissan - aborlas2019-12-17T06:00:00Zhttps://d.moonfire.us/blog/2019/12/17/lexember/On Lexember 17, 2019, I present "aborlas" as "to split a family away from a tribe."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 17: aborlas</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ə.bɔɪr.ljɑːs/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To split a family away from a tribe.</li>
<li>To perform subtraction.</li>
<li>To drain an area entirely of magic.</li>
</ol>
Lexember 16 - Hissan - clitici2019-12-16T06:00:00Zhttps://d.moonfire.us/blog/2019/12/16/lexember/On Lexember 16, 2019, I present "clitici" as "to have a family join a tribe."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 16: clitici</h1>
<h2>Pronunciation</h2>
<ul>
<li>/klɪt.iː.ʃi:/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To have a family join a tribe.</li>
<li>To perform addition.</li>
</ol>
Lexember 15 - Hissan - ookna2019-12-15T06:00:00Zhttps://d.moonfire.us/blog/2019/12/15/lexember/On Lexember 15, 2019, I present "ookna" as "to perform a ritual."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 15: ookna</h1>
<h2>Pronunciation</h2>
<ul>
<li>/uːk.njɑː/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To perform a ritual.</li>
<li>To be respectful of another family's or culture's traditions.</li>
<li>(Derogatory) To not question actions that were decided by long-dead generations.</li>
</ol>
Lexember 14 - Hissan - gyolas2019-12-14T06:00:00Zhttps://d.moonfire.us/blog/2019/12/14/lexember/On Lexember 14, 2019, I present "gyolas" as "a tradition or convention that has been obseved for multiple generations."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 14: gyolas</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ɡaʊ.lɑːs/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A tradition or convention that has been obseved for multiple generations.</li>
<li>The right and privileged a mother has for leadership.</li>
<li>(Derogatory) Situations when an unmarried man or child is supposed to remain silent.</li>
</ol>
Lexember 13 - Hissan - toysa2019-12-13T06:00:00Zhttps://d.moonfire.us/blog/2019/12/13/lexember/On Lexember 13, 2019, I present "toysa" as "to clean up the land before leaving."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 13: toysa</h1>
<h2>Pronunciation</h2>
<ul>
<li>/tɒ.ɛsɑː/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To clean up the land before leaving.</li>
<li>To frantically clean up a mess before someone finds it.</li>
<li>(Derogatory) To hide any signs of mastrubating.</li>
</ol>
Lexember 12 - Hissan - ca2019-12-12T06:00:00Zhttps://d.moonfire.us/blog/2019/12/12/lexember/On Lexember 12, 2019, I present "ca" as "to travel by walking."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 12: ca</h1>
<h2>Pronunciation</h2>
<ul>
<li>/tʃæ/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To travel by walking.</li>
<li>To take a long, slow journey across the land.</li>
<li>To speak in a long, meandering manner.</li>
<li>To give a long-winded lecture.</li>
</ol>
Lexember 11 - Hissan - as2019-12-11T06:00:00Zhttps://d.moonfire.us/blog/2019/12/11/lexember/On Lexember 11, 2019, I present "as" as "to move air by exhalation, to blow."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 11: as</h1>
<h2>Pronunciation</h2>
<ul>
<li>/æs/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To move air by exhalation, to blow.</li>
<li>To move air due to weather-related reasons.</li>
</ol>
Lexember 10 - Hissan - boosly2019-12-10T06:00:00Zhttps://d.moonfire.us/blog/2019/12/10/lexember/On Lexember 10, 2019, I present "boosly" as "to walk away from a fight to calm down."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 10: boosly</h1>
<h2>Pronunciation</h2>
<ul>
<li>/buːsj.lɪ/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To walk away from a fight to calm down.</li>
<li>To take time to recover from an injury or exhaustion.</li>
</ol>
Lexember 9 - Hissan - flinork2019-12-09T06:00:00Zhttps://d.moonfire.us/blog/2019/12/09/lexember/On Lexember 9, 2019, I present "flinork" as "the violent reaction of disharmonious magical energies."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 9: flinork</h1>
<h2>Pronunciation</h2>
<ul>
<li>/fli:n.ʊrk/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>The violent reaction of disharmonious magical energies.</li>
<li>A family feud that shows no sign of stopping.</li>
</ol>
Lexember 8 - Hissan - adysin2019-12-08T06:00:00Zhttps://d.moonfire.us/blog/2019/12/08/lexember/On Lexember 8, 2019, I present "adysin" as "to accept the vows of marriage."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 8: adysin</h1>
<h2>Pronunciation</h2>
<ul>
<li>/æ.ds.i:n/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To accept the vows of marriage.</li>
<li>To commit to a long-term relationship.</li>
</ol>
Lexember 7 - Hissan - oplin2019-12-07T06:00:00Zhttps://d.moonfire.us/blog/2019/12/07/lexember/On Lexember 7, 2019, I present "oplin" as "to change the frequency of magic to match another."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 7: oplin</h1>
<h2>Pronunciation</h2>
<ul>
<li>/oʊp.li:n/</li>
</ul>
<h2>Verb</h2>
<ol>
<li>To change the frequency of magic to match another.</li>
<li>To give up in an argument just to end it.</li>
</ol>
Lexember 6 - Hissan - gsach2019-12-06T06:00:00Zhttps://d.moonfire.us/blog/2019/12/06/lexember/On Lexember 6, 2019, I present "gsach" as "the resonance of magical energies interacting."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 6: gsach</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ɡs.ɑːx/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>The resonance of magical energies interacting.</li>
<li>A piercing cry of a child in danger.</li>
<li>A bird call.</li>
</ol>
Lexember 5 - Hissan - gsubi2019-12-05T06:00:00Zhttps://d.moonfire.us/blog/2019/12/05/lexember/On Lexember 5, 2019, I present "gsubi" as "a marriage between two people."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 5: gsubi</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ɡs.ʌbɪ/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A marriage between two people.</li>
<li>A long relationship that lasts for years.</li>
</ol>
Lexember 4 - Hissan - shik2019-12-04T06:00:00Zhttps://d.moonfire.us/blog/2019/12/04/lexember/On Lexember 4, 2019, I present "shik" as "a supernatural force that affects the world."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 4: shik</h1>
<h2>Pronunciation</h2>
<ul>
<li>/ʃi:k/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A supernatural force that affects the world.</li>
</ol>
Lexember 3 - Hissan - kasi2019-12-03T06:00:00Zhttps://d.moonfire.us/blog/2019/12/03/lexember/On Lexember 3, 2019, I present "kasi" as "a tract of land."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 3: kasi</h1>
<h2>Pronunciation</h2>
<ul>
<li>/kɔ:s.i:/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A tract of land.</li>
<li>An area defined by natural boundaries.</li>
</ol>
Lexember 2 - Hissan - misa2019-12-02T06:00:00Zhttps://d.moonfire.us/blog/2019/12/02/lexember/On Lexember 2, 2019, I present "misa" as "a strong wind."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 2: misa</h1>
<h2>Pronunciation</h2>
<ul>
<li>/mi:s.ɑ:/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>A strong wind.</li>
</ol>
Lexember 1 - Hissan - soli2019-12-01T06:00:00Zhttps://d.moonfire.us/blog/2019/12/01/lexember/On Lexember 1, 2019, I present "soli" as "the aggregate of solid mineral formations that makes up bedrock or the earth's crust."<p>This is the third year I'm participating in <a href="https://www.frathwiki.com/Lexember">Lexember</a>, a month-long challenge to come up with a new word a day for one of my conlangs. This year, I'm doing Hissan, a recent I've started working on for my development of the United Hidanork Tribes (UHT).</p>
<p>Like every other year, I'm also doing a theme. Since families and lands are tied closely together, the words I'm picking will be based on those related terms.</p>
<h1>Lexember 1: soli</h1>
<h2>Pronunciation</h2>
<ul>
<li>/soʊl.i:/</li>
</ul>
<h2>Noun</h2>
<ol>
<li>(Geological, Uncountable) The aggregate of solid mineral formations that makes up bedrock or the earth's crust.</li>
<li>A boulder or large stone.</li>
<li>A naturally occuring mineral formation.</li>
<li>A group of families that travel together.</li>
</ol>
Future Plans2019-07-24T05:00:00Zhttps://d.moonfire.us/blog/2019/07/24/future-plans/An update on near- and long-term plans for my writing and updates on this site. Also status on my Pride Month challenge stories, various novels, and financial plans.
<p>This week is one of those milestones in my life. It isn't a big one, at least no certificates or fireworks to herald its coming, but meaningful for my personal goals over the last fifteen years. Our youngest is finally out of daycare. That means I can move to the next step which is use the money we needed for daycare to reduce our debt and reduce our financial risk. I'm guessing that this will take about two years.</p>
<p>Naturally, just the hint of having more money meant everything started breaking down including the dishwasher giving up the ghost, a car bumper almost falling off, a kitchen light burning out, and a slew of other expenses. On the other hand, they thankfully waited until we <em>could</em> afford to handle them, so it is just one more thing.</p>
<p>Debt is a nasty thing. It is expensive to carry it but it is also very difficult to get out from underneath it once you get into the hole. To dig oneself out, it requires a discipline I don't always have and a lot of patience (years in this case).</p>
<p>Related to that, I want to get a book out but I shouldn't. I have two that are effectively done now (<a href="https://fedran.com/flight-of-the-scions/">Flight of the Scions</a> and <a href="https://fedran.com/second-hand-dresses/">Second-Hand Dresses</a>) with a third (<a href="https://fedran.com/raging-alone/">Raging Alone</a>) that should be done by end of year. They all require at least one editor round.</p>
<p>My updated plans are to publish either <em>Flight of the Scions</em> or <em>Second-Hand Dresses</em> in time for <a href="https://iowa-icon.com/">ICON</a> in 2021. Then one or two books in 2022.</p>
<p>The idea of two to three years is one of the frustrating part. I don't want to wait so long to get a book out but that is how my priorities go. As I mentioned before, a lot of my focus on tasks comes from something I read in Reader's Digest a long time ago.</p>
<blockquote>
<p>You have time for only three things in your life. It may be family, work, or a hobby. Pick those three and don't worry about the less.</p>
</blockquote>
<p>The above quote is paraphrased with the haze of decades. My three things are: family, work, and writing.</p>
<p>I'm still planning on posting a chapter every week at <a href="https://fedran.com/">fedran.com</a>. I've been doing that for four years now and it's becoming a thing.</p>
<p>On the other hand, I not going to update <a href="/">d.moonfire.us</a> with the chapter announcements. When I was always working on a single piece at a time, it was easy to set up announcements between the two. However, with the self-doubt of <em>Raging Alone</em> and my <a href="/blog/2019/06/01/pride-month/">Pride Month</a> challenge, that got disrupted and I don't think it's worth the energy to maintain inconsistent schedules on two sites. The Fedran website will always have the chapters.</p>
<p>Speaking of Pride Month, I finished it but it was tight. I ended up writing four stories but one of them got switched to serializing weekly to give me a bit of breathing room (and it was much longer):</p>
<ul>
<li><a href="https://fedran.com/let-his-memory-go/">Let His Memory Go</a>: This is a story I talked about in <a href="/blog/2015/10/28/sand-and-ash-13/">2015</a> about Mikáryo knowing that Rutejìmo was about to experience in <a href="https://fedran.com/sand-and-ash/">Sand and Ash</a>. This has some naughty scenes in it. It is fully posted on the site and has gone through my writing group.</li>
<li><a href="https://fedran.com/may-i-lead-this-dance/">May I Lead This Dance</a>: Spinning off <a href="https://fedran.com/second-hand-dresses/">Second-Hand Dresses</a>, I wanted to write about a trans girl who wants to go to a Tarsan party but is scared to because everyone sees her as a boy. I mean, Lily is poly and bi on the page but she's still cis in society. It is fully posted on the site but still going through the writing group so it has some rough edges.</li>
<li><a href="https://fedran.com/prospects-of-love-among-mages/">Prospects of Love Among Mages</a>: Related to my forensic murder mystery stories and novels, this is a story about four mages in the city guard talking about love and sex (or a lack of thereof). It a story with an ace, an aro, and a polyam while touching on depression, support networks, and being on the autism spectrum. It is fully posted on the site and has gone through my writing group.</li>
<li><a href="https://fedran.com/coins-for-your-troubles/">Coins for Your Troubles</a>: The longest piece about a lesbian warrior who gets injuries and spends a month recuperating at a small inn that she once saw a pretty girl. This has some naughty scenes in it. This is serializing until mid-August and my writing group hasn't seen it, so it is very rough.</li>
</ul>
<p>Opinions, comments, and the like is always appreciated. Otherwise, enjoy reading and tell me what you think.</p>
Pride Month Challenge2019-06-01T05:00:00Zhttps://d.moonfire.us/blog/2019/06/01/pride-month/Over the last few months, I've been berating myself about representation of queer characters in my world. Last year, I made a [list on Twitter](https://twitter.com/dmoonfire/status/1012520274695213061) about some of the queers that I've already introduced. Those haven't changed but I realized that I'm had not made any of those characters obvious that they were queer despite the fact they are and have been from the beginning.
<p>Over the last few months, I've been berating myself about representation of queer characters in my world. Last year, I made a <a href="https://twitter.com/dmoonfire/status/1012520274695213061">list on Twitter</a> about some of the queers that I've already introduced. Those haven't changed but I realized that I'm had not made any of those characters obvious that they were queer despite the fact they are and have been from the beginning. In a more crass view, it pretty much comes off as:</p>
<blockquote>
<p>J.K. Rowling Confirms Some Characters in Her Books and Movies Are Gay Everywhere Except in the Books or the Movies — <a href="https://twitter.com/EricDSnider/status/1107065804464361473">Snider D. Eric</a></p>
</blockquote>
<p>Now, some of it is because I write unreliable narrators from a single point-of-view character. That means if someone is not presenting their queer nature, the reader won't see it either. So Kanéko wouldn't ever know that her father had been bi for a short period of his life just as Rutejìmo wouldn't ever have the opportunity to find out that Hyonèku was ace (asexual). Even Lily didn't realize that all three of her lovers were bi until it came up in the story.</p>
<p>A good example of me being too subtle:</p>
<blockquote>
<p>Desòchu's face purpled. “Kiríshi isn't your wife!”</p>
<p>Gemènyo turned to Kiríshi with mock surprise on his face. “You aren't!?”</p>
<p>“No, I'm not.” Kiríshi rolled her eyes and smirked. Under her words, there was a hardness that Rutejìmo had never heard before.</p>
<p>“Want to be?”</p>
<p>“With your pipe?” Kiríshi made a disgusted look. “I'd rather sleep in the garbage. I still don't know how Ríhyo can stand you.”</p>
</blockquote>
<p>Has another meaning if you know that Kiríshi still has sex with Gemènyo when she needs intimacy because Hyonèku has almost no desire for sex, only companionship. Their effort to keep that from the public view relates to the way she responds to Gemènyo.</p>
<p>I have a good idea of why my characters are private however having <em>everyone</em> hiding it would violate one of the reasons I'm writing <a href="https://fedran.com/">Fedran</a> which is to show a variety of different personalities and beliefs that matches my observation of our own world.</p>
<p>Now that I see the problem, I want to fix it. Going forward, I want to show characters more “out” than I have in the past.</p>
<p><a href="https://en.wikipedia.org/wiki/Gay_pride">Pride Month</a> seems like a good time to do that. To push myself, I'm planning on writing four short stories over this month. They will focus on queer characters being out in the open.</p>
<p>If anything, it would help me break this shell of having everyone quiet about their sexuality. It will also give me a break I need from <a href="https://fedran.com/raging-alone/">Raging Alone</a> which my local writing group appears to despise and I've gotten very discouraged writing it. (<em>Raging Alone</em> is also my challenge to write a character who holds a grudge and is angry, two things I also struggle with.)</p>
<p>The first two stories I have planned are:</p>
<ul>
<li><em>Let His Memory Go</em>: This is a story I talked about in <a href="/blog/2015/10/28/sand-and-ash-13/">2015</a> about Mikáryo knowing that Rutejìmo was about to experience in <a href="https://fedran.com/sand-and-ash/">Sand and Ash</a>.</li>
<li><em>Her First Dance</em>: Spinning off <a href="https://fedran.com/second-hand-dresses/">Second-Hand Dresses</a>, I wanted to write about a trans girl who wants to go to a Tarsan party but is scared to because everyone sees her as a boy. I mean, Lily is poly and bi on the page but she's still cis in society.</li>
</ul>
<p>For the other two, I haven't really decided what I want to write. Ideally they would be “post” stories that establish new cultures or locations as opposed to branching from an existing novel.</p>
Author Intrusion and Naming Languages2019-05-02T05:00:00Zhttps://d.moonfire.us/blog/2019/05/02/author-intrusion/This week I submitted chapters three and four of [Raging Alone](https://fedran.com/raging-alone/) to the writing group. There were some good points made but one of the ones that the entire table brought up was the names. I figured that I could use the tool I just wrote to find out how bad it was.
<p>This week I submitted chapters three and four of <a href="https://fedran.com/raging-alone/">Raging Alone</a> to the writing group. There were some good points made but one of the ones that the entire table brought up was the names.</p>
<p>Like <a href="https://fedran.com/sand-and-blood/">Sand and Blood</a>, <em>Raging Alone</em> is focused around a small, isolated clan in the desert. The language and the names were inspired by people I've worked with over the years with a healthy borrowing from French and Japanese. However, they appear not to be names that are easy for English readers to <a href="/blog/2012/10/25/introduction-to-miwafu/">understand</a>.</p>
<p>Once I figured that out, I made a point of having <em>Sand and Blood</em> start off slowly to introduce characters and conventions gradually instead of throwing a lot of names quickly at the reader. In some ways, it ended up coloring that entire piece; more than once I was told it started off too slowly which dragged out Rutejìmo's flaws.</p>
<p>With <em>Raging Alone</em>, though I got much of the same thing. However, since I just finished a round of <a href="/tags/author-intrusion/">Author Intrusion</a>, I realized I could quantify my efforts using what I just finished writing <a href="/blog/2019/04/30/author-intrusion/">wrote</a>.</p>
<h1>Metadata</h1>
<p>I keep information about the chapter in the top of each file in a YAML “front matter”.</p>
<pre><code>---
title: Sulking
characters:
primary: [Desòchu]
secondary: [Kiramíro]
referenced: [Gemènyo, Hyonèku, Kiríshi, Chyojímo, Hikòru]
---
> There is no more graceless being than a teenage boy coming into his age. --- Nagufiga Makinàfu, *Sexuality Among the Sands*
Like most typical days in Shimusogo Valley, the hot midday blew winds...
</code></pre>
<p>The key part is the <code>characters</code> section which lists the point of view (<code>primary</code>), characters in the chapter (<code>secondary</code>), and those who are talked about but not present (<code>referenced</code>).</p>
<p><em>This is also what is used to populate the footer of the chapters such as <a href="https://fedran.com/raging-alone/chapter-01/">this one</a> at the bottom.</em></p>
<h1>Author Intrusion</h1>
<p>Using the <a href="/blog/2019/04/30/author-intrusion/">last post</a> for setup, I can use <a href="http://jmespath.org/">JMESPath</a> to create a comma-separated list of characters that are in the chapter.</p>
<p>If I just wanted a list of secondary characters, I would use: <code>characters.secondary[] | sort(@) | join(', ', @)</code> which says get all the items from <code>characters.secondary</code>, then sort them, then combine them together.</p>
<p>If I want all the characters from all three categories (<code>primary</code>, <code>secondary</code>, and <code>referenced</code>), I can just replace <code>secondary</code> with <code>*</code> to get <code>characters.*[] | sort(@) | join(', ', @)</code>.</p>
<p>Related to that, I can also get the count of character in the chapter with: <code>characters.*[] | length(@)</code>.</p>
<h1>Analysis</h1>
<p>Running the tool on the first five chapters of <em>Sand and Blood</em>, I get:</p>
<pre><code>$ author-intrusion chapter list -f file.num -f title -f "characters.*[] | length(@)" -f "characters.*[] | sort(@) | join(', ', @)"
</code></pre>
<table>
<thead>
<tr>
<th style="text-align: right;">Num</th>
<th>Title</th>
<th style="text-align: right;">Count</th>
<th>Characters</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right;">1</td>
<td>Rutejìmo</td>
<td style="text-align: right;">7</td>
<td>Chimípu, Ganósho, Gemènyo, Hyonèku, Rutejìmo, Tejíko, Yutsupazéso</td>
</tr>
<tr>
<td style="text-align: right;">2</td>
<td>Confession</td>
<td style="text-align: right;">10</td>
<td>Byodenóre, Chimípu, Desòchu, Gemènyo, Hyonèku, Rador, Rutejìmo, Shimusògo, Somiryòki, Tejíko</td>
</tr>
<tr>
<td style="text-align: right;">3</td>
<td>Morning</td>
<td style="text-align: right;">17</td>
<td>Chimípu, Desòchu, Gemènyo, Hyonèku, Kizúchi, Laminar, Mapábyo, Mifuníko, Nidohána, Ojinkomàsu, Opōgyo, Panédo, Rutejìmo, Tachìra, Tachìra, Tejíko, Yutsupazéso</td>
</tr>
<tr>
<td style="text-align: right;">4</td>
<td>Rivals</td>
<td style="text-align: right;">6</td>
<td>Desòchu, Karawàbi, Palasaid, Rutejìmo, Tejíko, Tsubàyo</td>
</tr>
<tr>
<td style="text-align: right;">5</td>
<td>Decisions</td>
<td style="text-align: right;">14</td>
<td>Chimípu, Desòchu, Gemènyo, Goryápe, Karawàbi, Mapábyo, Mifuníko, Pidòhu, Rutejìmo, Shimusògo, Somiryòki, Tejíko, Tsubàyo, Yutsupazéso</td>
</tr>
</tbody>
</table>
<p>Well, seen this way, I didn't do a very good job of “gradually” introducing character names at all. One might said I did an absolutely terrible job of introducing the constructed language. I guess that points out that a subjective belief verses objective analysis.</p>
<p>Now, I don't distinguish characters who are there but not named so the list is smaller. Below is a quick test of the seven names in the first chapter. I use <code>expr - 1</code> because there is the entry in the matter which I don't want to include and readers don't see.</p>
<pre><code>sand-and-blood$ for i in Chimípu Ganósho Gemènyo Hyonèku Rutejìmo Tejíko Yutsupazéso;do echo -n "$i: "; echo $(expr $(grep $i chapter-01.markdown | wc -l) - 1); done
Chimípu: 2
Ganósho: 0
Gemènyo: 1
Hyonèku: 22
Rutejìmo: 23
Tejíko: 0
Yutsupazéso: 3
sand-and-blood$
</code></pre>
<p>Above you can see that Ganósho and Tejíko were not listed by name but the others did. Regardless, what I thought was a gradual introduction was closer to me throwing a bowlful of names at the reader and saying “here you go!”</p>
<p>Let's see if I did better with <em>Raging Alone</em>:</p>
<table>
<thead>
<tr>
<th style="text-align: right;">Num</th>
<th>Title</th>
<th style="text-align: right;">Count</th>
<th>Characters</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right;">1</td>
<td>Sulking</td>
<td style="text-align: right;">7</td>
<td>Chyojímo, Desòchu, Gemènyo, Hikòru, Hyonèku, Kiramíro, Kiríshi</td>
</tr>
<tr>
<td style="text-align: right;">2</td>
<td>Comfort</td>
<td style="text-align: right;">5</td>
<td>Chyojímo, Desòchu, Hikòru, Hyonèku, Kiramíro</td>
</tr>
<tr>
<td style="text-align: right;">3</td>
<td>The Call</td>
<td style="text-align: right;">8</td>
<td>Chyojímo, Desòchu, Hikòru, Kiramíro, Pikonàga, Somiryòki, Tejíko, Yutsupazéso</td>
</tr>
<tr>
<td style="text-align: right;">4</td>
<td>Baby Brother</td>
<td style="text-align: right;">4</td>
<td>Chyojímo, Desòchu, Rutejìmo, Tachìra</td>
</tr>
<tr>
<td style="text-align: right;">5</td>
<td>Waking Up</td>
<td style="text-align: right;">5</td>
<td>Desòchu, Kiríshi, Rutejìmo, Somiryòki, Tejíko</td>
</tr>
</tbody>
</table>
<p>Well, I've done a lot better job of reducing how many names are thrown at the reader but it also points out I'm still throwing a lot of them in the first chapter. Getting that number down to four or five would make it an easier introduction and points out a possible place to trim down the story. In the writing group, we found a way of cutting out two or three names out of “The Call” which would make it much more manageable.</p>
<p>Now, chapter five is the “inciting event”, so where I would normally split a chapter, I would probably want to add it after chapter five so we get to the “big event” faster. But that's for another blog post.</p>
<h1>Conclusion</h1>
<p>Sometimes, its hard as an author to see problems in the story while writing it. One of the reasons I created Author Intrusion was to help me focus them the problem I struggled to see. In this case, I thought I was being gradual with names but once it was pointed out, it was obvious I was not.</p>
<p>I also realized there are some additional checkers I could include to help identify these problems while writing:</p>
<ul>
<li><a href="https://gitlab.com/author-intrusion/author-intrusion-rust/issues/17">#17</a>: Introduce a checker that counts a number of entries (a JMESPath such as one against characters) against a threshold</li>
<li><a href="https://gitlab.com/author-intrusion/author-intrusion-rust/issues/18">#18</a>: Ensure that every chapter has an epigraph (my style guide)</li>
<li><a href="https://gitlab.com/author-intrusion/author-intrusion-rust/issues/18">#19</a>: Check that a character in narrative is identified in the metadata.</li>
</ul>
Author Intrusion - I've Been Here Before2019-04-30T05:00:00Zhttps://d.moonfire.us/blog/2019/04/30/author-intrusion/When it comes to projects that I probably will never finish, Author Intrusion is probably right up there. Most of the time, it is because I keep restarting because I learned significant lessons. This last week was one of those cases.
<p>When it comes to projects that I probably will never finish, <a href="/tags/author-intrusion/">Author Intrusion</a> is probably right up there. Most of the time, it is because I keep restarting because I learned significant lessons. This last week was one of those cases.</p>
<p>Author Intrusion is also one of those projects that I keep coming back because I <em>know</em> it can help me but it requires a lot of effort to turn what I think I need into something that is useful. One might say that is obvious from the sheer number of times I restarted development but it is a moving target even from the beginning.</p>
<p>There are a lot of reasons for the various restarts:</p>
<ul>
<li>Can't handle my 25k word penultimate chapter on a project:
<ul>
<li>... in a reasonable time.</li>
<li>... or with reasonable memory concerns.</li>
<li>... or without grinding my entire system to a halt.</li>
</ul>
</li>
<li>Can't handle my 600k word epic:
<ul>
<li>... in a reasonable time, overloading my memory, and stopping my machine.</li>
</ul>
</li>
<li>Couldn't figure out how to determine parts of speech correctly.</li>
<li>I tried to:
<ul>
<li>... write an entire text editor.</li>
<li>... okay, just the text control.</li>
<li>... okay, just load single chapters.</li>
<li>... okay, just a CLI to parse the files.</li>
</ul>
</li>
</ul>
<p>This is over eight years of struggling with this tool.</p>
<h1>Expectations</h1>
<p>Part of the problem is I'm thinking too grandly. I always had that problem when I can't code, silence is probably the worse things for my plots and my projects. I think I've managed to winnow down the list to a more obtainable set of goals:</p>
<ul>
<li>Work with YAML + Markdown, my preferred format.</li>
<li>Analyze the chapters of the book at:
<ul>
<li>Identify problem words.</li>
<li>Identify clustered echo words.</li>
</ul>
</li>
<li>Get me a good count of words for the chapters:
<ul>
<li>... for the entire book.</li>
<li>... for a range of chapters.</li>
</ul>
</li>
<li>Identify sentences:
<ul>
<li>... that start with the same pattern.</li>
<li>... have the same number of words.</li>
</ul>
</li>
<li>Identify concurrent paragraphs that start with the same word.</li>
<li>Identify overuses of gerunds (a category of <code>-ing</code> words).</li>
<li>Identify overuses/clusters of “to be” verbs.</li>
<li>Allow me to insert a chapter easily.</li>
<li>Identify present tense outside of dialog.</li>
<li>Integrate with <a href="https://atom.io/">Atom</a> as a language service.</li>
<li>Work on Windows and Linux.</li>
<li>Handle custom spelling.</li>
</ul>
<p>Okay… that isn't that much of a shorter list. Even so, it will take a while to even get close to it despite these features being 90% of what I use tools to do today.</p>
<h1>The Last Failure</h1>
<p>The last version used <a href="https://en.wikipedia.org/wiki/XPath">XPath</a> and <a href="https://en.wikipedia.org/wiki/XSLT">XSLT</a>. I figured it was a good way of framing the ideas, however I started getting bogged down in making it <em>flexible</em> because I hate the idea of opinionated systems and didn't want to force others to work the way I work (blame James White's <em>Fast Trip</em> for that).</p>
<p>Also, it struggled with the large files and projects.</p>
<p>When I encounter a problem, sometimes it is good to think of it in a different way. This might require retooling it, starting over (I did that with RPG games a lot as a kid too), or trying to come around the problem a different way.</p>
<h1>Rust Language</h1>
<p>I decided to spend a week trying another iteration of Author Intrusion. This time, I used it as a learning experience for an entirely different (and new to me) language: <a href="https://www.rust-lang.org/">Rust</a>. Rust is a pretty low-level language but has much of the packaging and niceties of C# (my primary language). Since I knew the initial versions of Author Intrusion so well (I have restarted over ten times), it was old territory that would make it easier to map the language into something I already knew.</p>
<p>Overall, Rust is fairly pleasant to use but there are places where I struggled a lot with it conceptually. I've worked in object-oriented languages for the last twenty years, Rust has some OO-like support but I had to change how I was working to use it. Also I still haven't groked the “borrow” concepts enough, so sometimes I just revert to randomly adding and removing <code>&</code> and <code>*</code> in hopes of figuring it out.</p>
<p><em>In other words, I beat on it like a black obelisk.</em></p>
<p>The tooling with Rust is considerably poorer than C#. Not being able to refactor easily definitely ate up significant time in the last week. Also my laptop hates working with Rust, it gets burning hot after only an hour of coding… which was good because I put it down until everything cooled off.</p>
<p>That said, I've been pretty happy with the results so far so I'm hoping to keep it going with this variant instead of the previous ones, at least to see if I can get closer to my end goals.</p>
<h1>Running the Tool</h1>
<p>So, if you are interested in checking it out with this post, head over the the <a href="https://gitlab.com/author-intrusion/author-intrusion-rust">GitLab repository</a> and clone it. I'm using <code>rustup</code> for my installation with the nightly builds, so the following should work:</p>
<pre><code>$ git clone https://gitlab.com/author-intrusion/author-intrusion-rust
$ cd author-intrusion-rust
$ ./run-000 chapter list
</code></pre>
<p>On Linux, I create an alias to run it from anywhere:</p>
<pre><code>$ alias author-intrusion="cargo run --quiet --"
</code></pre>
<p>Unless noted, I'll also run all of these examples from the <code>./examples/000-simple-project</code> directory.</p>
<h1>Project Files</h1>
<p>Like before, everything hangs off a <code>author-intrusion.aipry</code> project file. This tells the system where the root of the project is located (I love being able to use <code>npm</code> and <code>gulp</code> from sub-directories) and how the project is organized.</p>
<p>The project file is a YAML file. There are two examples in the <code>./examples/</code> folder in the source code.</p>
<pre><code>name: First Example Project
content:
pattern: chapters/chapter-??.md
</code></pre>
<p>The <code>name</code> is just there because I like to have something.</p>
<p>The <code>content</code> chapter says how the project is organized for the actual content. Now, in my case, I almost universally use <code>chapter</code> for my files but I've been switching from <code>chapter-01.markdown</code> to <code>chapter-01.md</code>. Someone might prefer a different approach (like the <code>src</code> directory or eventually a chapter/scene approach).</p>
<h1>File List</h1>
<p>With that, we have the basic ability to list chapters.</p>
<pre><code>$ author-intrusion chapter list
chapters/chapter-01.md 1 Chapter One 9
chapters/chapter-02.md 2 Chapter Two 11
$
</code></pre>
<p>This shows off some of the cool things it can do already. The first column is the relative path in project. This is the same as adding <code>-f file.rel_path</code> to the command.</p>
<p>The second column is the chapter number which is parsed from the file (<code>chapter-01.md</code> -> <code>01</code> -> <code>1</code>). This is the same as <code>-f file.num</code>.</p>
<p>The third is pulled from the file itself in the front matter (the section between the <code>---</code> lines). This uses <a href="http://jmespath.org/">JMESPath</a> for the queries that lets you do some really tool things. In this case, it is just a simple <code>-f title</code> which pulls the <code>title:</code> line from the files.</p>
<p>Finally, the last column is the number of words inside the file or <code>-f count.words</code>.</p>
<p>The reason I have these individual fields is because maybe I only want the word count in each chapter.</p>
<pre><code>$ author-intrusion chapter list -f count.words
9
11
$
</code></pre>
<h1>Using JMESPath</h1>
<p>The JMESPath also lets me pull out more detailed information from the query. As I've shown in <a href="https://gitlab.com/fedran/sand-and-blood/blob/master/chapters/chapter-01.markdown">sample chapters</a>, I put a lot of information in the front matter to help me keep track of the book.</p>
<p>A simple case is chapter 1 of the example file:</p>
<pre><code>---
title: Chapter One
locations:
- Location A
- Location B
---
This is chapter 1 for Anton.
</code></pre>
<p>So, if I want to pull out the locations with the tool as a comma separated list, I can do the following.</p>
<pre><code>$ author-intrusion chapter list -f file.rel_path -f "locations[] | sort(@) | join(', ', @)"
chapters/chapter-01.md Location A, Location B
chapters/chapter-02.md
$
</code></pre>
<p>It looks more impressive with the second example, which is the first nineteen chapters of <a href="https://fedran.com/sand-and-blood/">Sand and Blood</a>. I can use that to list all the characters who are present in each chapter besides the main character:</p>
<pre><code>$ author-intrusion chapter list -f file.rel_path -f "characters.secondary[] | sort(@) | join(', ', @)" | head -n 3
chapters/chapter-01.markdown Hyonèku
chapters/chapter-02.markdown Gemènyo, Somiryòki, Tejíko
chapters/chapter-03.markdown Desòchu, Gemènyo, Hyonèku, Mapábyo, Opōgyo, Panédo
$
</code></pre>
<p>This is also Unicode-friendly, which is important to me since I'm fond of constructed languages and have a number of them for my world.</p>
<h2>Defining Field Aliases</h2>
<p>Now, that can get really wordy, so I added the ability to save those fields in the project file:</p>
<pre><code>name: Sand and Blood by D. Moonfire
content:
pattern: chapters/chapter-??.markdown
query:
fields:
characters.secondary:
jmes: characters.secondary[] | sort(@) | join(', ', @)
</code></pre>
<p>That way, they can be easily used as an aliased field:</p>
<pre><code>$ author-intrusion chapter list -f file.rel_path -f characters.secondary
chapters/chapter-01.markdown Hyonèku
chapters/chapter-02.markdown Gemènyo, Somiryòki, Tejíko
chapters/chapter-03.markdown Desòchu, Gemènyo, Hyonèku, Mapábyo, Opōgyo, Panédo
$
</code></pre>
<h1>Analysis</h1>
<p>The other part I managed to get done this week is the basic version of checking. Using <em>Sand and Blood</em> as an example, I have a problem with an overuse of “sigh” and “sighed”. I can use the tool to highlight when I start to use it too much.</p>
<p>To do that, I first define a check in the project file:</p>
<pre><code>name: Sand and Blood by D. Moonfire
content:
pattern: chapters/chapter-??.markdown
checks:
- overused_pattern:
# The `(?i)` makes this case insensitive.
pattern: "^(?i)(sigh|sighed)$"
err: 0.002
warn: 0.001
</code></pre>
<p>The <code>err</code> and <code>warn</code> are ratios in the file. So, <code>0.002</code> means if more than 0.2% of the chapter is sighing, then just flag them as errors.</p>
<pre><code>$ author-intrusion check
chapters/chapter-01.markdown:100:17: warning: found overused word "sighed"
chapters/chapter-01.markdown:140:11: warning: found overused word "sighed"
chapters/chapter-02.markdown:92:230: warning: found overused word "sighed"
chapters/chapter-02.markdown:120:48: warning: found overused word "sigh"
chapters/chapter-02.markdown:214:8: warning: found overused word "sigh"
$
</code></pre>
<p>The message is formatted so most tools like Atom or Emacs will move you the line and first character of the word being reported. And they can highlight the lines as yellow or red depending on the <code>warning</code> or <code>error</code>.</p>
<h2>Additional Problems</h2>
<p>The “sighing” problem was also mirrored by a “nodding” one. So, once I identify that word as a problem, I can add it to the file:</p>
<pre><code>checks:
- overused_pattern:
# The `(?i)` makes this case insensitive.
pattern: "^(?i)(sigh|sighed)$"
err: 0.002
warn: 0.001
- overused_pattern:
pattern: "^(?i)(nod|nodded)$"
err: 0.002
warn: 0.001
</code></pre>
<p>Then it highlights each one as either a warning (under 0.2%) or error (0.2% or higher).</p>
<p><em>Side note, I'm probably going to rename it to <code>overused_word</code>.</em></p>
<h1>Speed</h1>
<p>The biggest test is how fast this thing is. I don't have a lot done, but I had it process almost three million words in all the chapters I've written in the last twenty years in about twelve seconds. Doing actual English checking (overused words, patterns) will take longer, but twelve seconds is a promising start.</p>
<p>Obviously, it will get slower once I put the various checks in, but this is better than the previous iteration at an hour to handle two million words.</p>
<h1>Conclusion</h1>
<p>So that is how much I got going in a week with a language I just started learning a week ago Saturday. I'm pretty happy with the results and in the process, I found a lot of places that I was over-engineering the code. While I don't know if I'll ever be “done” with this, I think this is currently my best viable approach and it already has something I can use for this coming week when I work on <a href="https://fedran.com/raging-alone/">Raging Alone</a>.</p>
Poem - Why Not Let it Be?2019-04-30T05:00:00Zhttps://d.moonfire.us/blog/2019/04/30/poem-2/For the final day of National Poetry Month, I present a poem about the Internet culture and unwanted discouragement.
<p>For the final day of National Poetry Month, I present a poem about the Internet culture and unwanted discouragement. This is based on many incidents when someone says “I like this” and then someone says “I don't and you shouldn't.” It doesn't have to be on the Internet, I've seen people ranting about gay couples in restaurants or bitching that someone wears their pants too low. It doesn't hurt anyone, so why not let it be?</p>
<p>Related to that, it doesn't have to be for me either. The saggy pants is not my thing. Watching hours of <em>Temple Run</em> on YouTube is not my thing, but if someone wants to do it? Let them. If someone asked to be called “they” or “him” or “her” or “mx”, then I'm the type of person who will do that. Let it be.</p>
<p>We all look for our sense of identity. When it is a new one, it doesn't quite fit as smoothly as one would like it to be. Realizing one is gay or lesbian or neither takes a while to adapt. Finding out that someone loves all genders or no genders or only close friends, it feels right but it also hasn't quite settled into place like a puzzle piece. So, let it be.</p>
<p>Sometimes it's a phase, sometimes it isn't. Sometimes you know from an early age that they are poly and pan. Other times, it hit someone in their forties that they like model trains, or BDSM, or teaching ceramics. It doesn't matter. Let it go.</p>
<p>Please, let people love what they love.</p>
<p>If you don't like it but it doesn't hurt anyone, then just… let it go.</p>
<p><em>Why Not Let it Be?</em></p>
<pre><code class="language-poem">She likes a book.
You don't read.
Why not let it be?
They like to draw.
You don't like it.
Why not let it be?
He liked a play.
You don't watch.
Why not let it be?
They like to game.
You don't play.
Why not let it be?
She loves a girl.
You don't approve.
Why not let it be?
They aren't a boy.
You don't agree.
Why not let it be?
</code></pre>
Poem - My Father's Ring2019-04-30T05:00:00Zhttps://d.moonfire.us/blog/2019/04/30/poem/On the thirthieth day of National Poetry Month, I present a poem about battle and fighting for a cause.
<p>On the thirthieth day of National Poetry Month, I present a poem about battle and fighting for a cause. The specific culture doesn't have a lot of details in my world yet, but <a href="https://fedran.com/hound-of-illustir/">The Hound of Illustir</a> will probably be one of the first (and my world's version of <em>Old Yeller</em>). It will be interesting because I only have a few notes so far and a number of <a href="https://fedran.com/almanac/">Almanac</a> entries.</p>
<p><em>My Father's Ring</em></p>
<pre><code class="language-poem">My father's ring
Worn in the Battle of Takair
He died a week later
Now I wear it to my own battle.
My father's father's ring
Cut from his finger in disgrace
His betrayal still hurts
Now I wear it to remind me to charge.
My father's father's father's ring
Forged when we still had a home
Shapes of irons he dug up
Now I wear it to survive.
My father's father's father's father's ring
Given to us by a foreigner
A payment for his youngest daughter
Now I wear it to save her children.
</code></pre>
Poem - A Child is Born2019-04-29T05:00:00Zhttps://d.moonfire.us/blog/2019/04/29/poem/For the twenty-ninth day of National Poetry Month, I wrote about poem about my son's first breath.
<p>For the twenty-ninth day of National Poetry Month, I wrote about poem about my son's first breath. Yeah, it's a bit more slanted for the world, but I actually managed to get a photograph of that first breath (both of my children were born with the cord around their necks). It was scary but also startling, a moment of silence as if the world was waiting for that first… single… breath.</p>
<p><em>A Child is Born</em></p>
<pre><code class="language-poem">A gasp of air.
A wail.
A cry.
A breath.
Crystal chimes ring out,
Cries rise up in cheerful harmony,
Music fills the heart,
Hands touch and caress with joy,
Tears dripping from faces,
Names are thrown out,
Promises are made happily,
Gifts are stacked high.
A child is born.
</code></pre>
Poem - Love Among Girls2019-04-28T05:00:00Zhttps://d.moonfire.us/blog/2019/04/28/poem/For the twenty-eight day of National Poetry Month, the theme is forbidden lesbian lovers.
<p>For the twenty-eight day of National Poetry Month, the theme is forbidden lesbian lovers. Why? Because my desert culture is aggressively homophobic for the sole reason I am not. This will come up in <a href="https://fedran.com/desert-child/">Desert Child</a> but the seeds are still there.</p>
<p><em>Love Among Girls</em></p>
<pre><code class="language-poem">She has the sweetest smile
That I want to kiss so badly.
I want to touch her hand
And rest my palm on her hip.
I tried, I tried so many times.
I've been beaten and caged.
My father no longer speaks.
My mother won't see me anymore.
I want the girl and she wants me.
But was even the hint of our desires
Enough to ruin our families?
To cast us among the clanless?
If I turn back, I might have a chance.
My family may speak to me again.
My clan name could return to my breast.
I'll have a home and a bed.
If I don't, what will she do?
Will she return and leave me?
Does she need her family more than me?
Is it love or just lust?
Can I survive alone in this desert?
With the hot sands burning my feed?
With no one to hold my hand
And no lips to caress in comfort?
She has the sweetest of smiles
Laughter that brings joy.
If she leaves, I have to accept it.
If she remains, then I will kiss her
And hold her until the end of days.
</code></pre>
Poem - Fifty-Three Years2019-04-27T05:00:00Zhttps://d.moonfire.us/blog/2019/04/27/poem/On the twenty-seventh day of National Poetry Month, I wrote a poem about my marriage.
<p>On the twenty-seventh day of National Poetry Month, I wrote a poem about my marriage. When I was getting married to my spouse in 2000, we talked about renewing vows. I wanted to renew every decade to give them a safe and easy “out” if they were ever tired of me. They wanted it to be forever… and maybe into the next life if possible.</p>
<p><em>Side note, I'm still trying to figure out how to haunt her to keep with her after I die.</em></p>
<p>We compromised on a fifty-year marriage. In 2050, we'll decide if we want to keep going or walk away. After fifty years, chances are, I'll stay, but the same thought remains: I don't want them to feel obligated to be married to me “because.”</p>
<p>This is the same philosophy I have with authors from <a href="https://typewriter.press/">Broken Typewriter Press</a>. They can walk away if they feel the need. Yeah, I'd hope they pay my costs but right now, if it doesn't work, then don't continue it.</p>
<p>I almost ended this poem with the way Buckminster Fuller died, but didn't.</p>
<p><em>Fifty-Three Years</em></p>
<pre><code class="language-poem">Fifty-three years as of this midnight.
So many years of looking into his face
And seeing the wrinkles spread across
And the eye glaze over with age.
So handsome.
Fifty-three years as of this midnight.
So many years of holding her tight
And seeing her breasts drop
And her hair go gray.
So beautiful.
Fifty-three years as of this midnight.
So many years of living together
And seeing our rings tarnish
And our children grow.
So wonderful.
Fifty-three years as of this midnight.
So many years of saying "I love you"
And repeating our vows
And remembering how to love.
So joyful.
</code></pre>
Poem - A Child On a Bed So Soft2019-04-26T05:00:00Zhttps://d.moonfire.us/blog/2019/04/26/poem/On the twenty-sixth day of National Poetry Month, I have a little poem about losing a child.
<p>On the twenty-sixth day of National Poetry Month, I have a little poem about losing a child. In a rough world, I have no doubt that this happens with depressingly frequent occurrence and I still see the lost of those around me who have lost their own children over the years. There really isn't a way I can't write about it.</p>
<p>This may also be inspired by a video I stumbled on years ago while browsing the Internet. It still haunts me.</p>
<p><em>A Child On a Bed So Soft</em></p>
<pre><code class="language-poem">a child on a bed so soft
eyes open but no longer seeing
her hand no longer grasps my thumb
fingers slack and splayed
a child on the deck so cold
the sea washing around us
my foot holding her hair down
to avoid our grief being stolen
a child wrapped in canvas
my mother's first blanket
my father's cherished belt
my tears on her chest
a child bobbing in the waves
face washed with salt
dress billowing in waves
the sea holding her tight
a child lost in the waves
one ribbon floating in the water
one aching hole in my heart
and a mother who will never not cry
</code></pre>
Poem - Yes, Sir, I Understand2019-04-25T05:00:00Zhttps://d.moonfire.us/blog/2019/04/25/poem/For the twenty-fifth day of National Poetry Month, I have a little poem about slavery and racism.
<p>For the twenty-fifth day of National Poetry Month, I have a little poem about slavery and racism. While I'm an apparently cis white male, there are some themes in my world about the former slavery of the <a href="https://fedran.com/dalpre/">dalpre</a>.</p>
<p>I'm not planning on writing a lot when they were slaves (not really my story) but I am planning on working out how society handles them after they are “freed” both from the point of the dalpre and for the humans.</p>
<p><em>Yes, Sir, I Understand</em></p>
<pre><code class="language-poem">"Dog, move that wagon."
Yes, Sir, I understand.
You don't care who I am
Only the fur on my back
And the muzzle on my mouth.
"Dog, carry those boxes."
Yes, Sir, I understand.
You don't see me as human
Only an animal that can listen
With fingers that break.
"Dog, build those gallows."
Yes, Sir, I understand.
You don't see this as a crime
Only breeding your pets
And getting rid of the bad ones.
"Dog, step up."
Yes, Sir, I understand.
You don't see me as a being
Only empty eyes that can't see
And my tail between my legs.
"Dog, rot in hell."
Yes, Sir, I understand.
You don't see me has someone
Only a beast that went too far
And bred with one of yours.
</code></pre>
Poem - She Speaks For Death2019-04-24T05:00:00Zhttps://d.moonfire.us/blog/2019/04/24/poem/For the twenty-fourth day of National Poetry Month, I have a little spoiler for a novel I'm planning on writing.
<p>For the twenty-fourth day of National Poetry Month, I have a little spoiler for a novel I'm planning on writing. If you read my novels, you can probably figure out who it is about but I could imagine there is something terrifying for any child who speaks for a spirit capable of killing anyone.</p>
<p>She is also one of my favorite side characters.</p>
<p><em>She Speaks For Death</em></p>
<pre><code class="language-poem">She's just a little girl.
Innocent with brown skin and green eyes.
Her words are quiet and infrequent
But terrifying just the same.
When she speaks, she speaks for death.
The full force of the desert behind her.
When she says quiet, then even magic dies.
When she says listen, she steals your air.
When she says no, there is no chance for yes.
Not even the sun and moon
Can refuse her anything.
She's just a little girl
But she speaks for death.
</code></pre>
Poem - Kill Them All2019-04-23T05:00:00Zhttps://d.moonfire.us/blog/2019/04/23/poem/**Content Warning for Suicide and Murder** For the twenty-third day of National Poetry Month, I have a poem about the horrors of growing up.
<p><strong>Content Warning for Suicide and Murder</strong></p>
<p>For the twenty-third day of National Poetry Month, I have a poem about the horrors of growing up. I've written before about my suicide attempt when I was seventeen. It was a rough time, one where the feeling of being alone and constantly mocked reached a peak. This is a poem that brings some of that back, so it might not be for everyone.</p>
<p>One thing that was thankful was that I've pretty much always been a pacifist. The idea of even hurting someone sickened me, despite the fact that one specific had tried to run me over with his car because I was involved with his suspension (he slammed my head into a locker hard enough to cause me to bleed).</p>
<p>High school was really hard on me.</p>
<p>However, what if I wasn't that way?</p>
<p><em>Kill Them All</em></p>
<pre><code class="language-poem">Endlessly mocking students
Watching all my movements.
Some know that I manifested
And let me know I'm detested.
Down the street and across the way
I wish they would just go away.
The hate is building inside me
And I don't know of my empathy.
I want to kill them every day
And see the bodies I slay.
My magic is already flowing
And my hands are glowing.
I want to kill them all
My fantasies are gore and vitriol.
I shouldn't and I can't.
I have to show restraint.
My dreams are violent
But my magic is silent.
</code></pre>
Poem - Pumps and Gears2019-04-22T05:00:00Zhttps://d.moonfire.us/blog/2019/04/22/poem/For the twenty-second day of National Poetry Month, I have a poem about steam engines.
<p>For the twenty-second day of National Poetry Month, I have a poem about steam engines. As I mentioned before, <a href="https://fedran.com/">Fedran</a> is on the cusp of two great ages: the descent of magic and the rise of machines. This is going to be an interesting time to say the least, but it is at a point where cars and trains are <em>new</em> and interesting to most people.</p>
<p><em>Pumps and Gears</em></p>
<pre><code class="language-poem">Fire roaring mutely
Metal groaning with pressure
Black smoke chugging
Boiler hissing steam
Gears squeaking in rhythm
Piston driving endlessly
Wheels turning forever
</code></pre>
Poem - The Stone and I Breathe2019-04-21T05:00:00Zhttps://d.moonfire.us/blog/2019/04/21/poem/For the first and twenty day of National Poetry Month, I wrote a poem about attuning oneself to rock.
<p>For the first and twenty day of National Poetry Month, I wrote a poem about attuning oneself to rock. This power is related to the Wamifūko in <a href="https://fedran.com/sand-and-ash/">Sand and Ash</a> but with a specific named character's coming of age that is planned for a future novel. Kanéko's father, Ronamar, also has similar experiences with stone being a Earth Knight of Kormar.</p>
<p><em>The Stone and I Breathe</em></p>
<pre><code class="language-poem">The stone below is still
My held breath burns my lungs
Nothing moves but the beat of my pulse
My chest burns with the need
The faintest of trembles
I opened my mouth
A quiver, a touch, a dance
I can finally let my breathe go
The ground stills once again
I inhale slowly but steadily
Nothing moves beneath my fingers
I hold my breath, waiting for the next
</code></pre>
Poem - Wisps of Clouds2019-04-20T05:00:00Zhttps://d.moonfire.us/blog/2019/04/20/poem/For the twentieth day of National Poetry Month, I have a little poem about flying. There is something about fliers I love, both the joy of losing oneself in the clouds but also the freedom to move.
<p>For the twentieth day of National Poetry Month, I have a little poem about flying. There is something about fliers I love, both the joy of losing oneself in the clouds but also the freedom to move. As a young one, I <em>adored</em> stories about races with wings. I even had a go-to favorite race of elves (my mithral elves from my old D&D world) that had wings.</p>
<p>In <a href="https://fedran.com/flight-of-the-scions/">Flight of the Scions</a>, I always had the plan to make Maris a flier. How it turned out, the casual collateral damage with an unexpected and happy part of her personality. This poem was written with her in mind, though it would probably be something that happens between the <a href="https://fedran.com/pack-daughter/">second</a> and <a href="https://fedran.com/son-of-vo/">third</a> book.</p>
<p><em>Wisps of Clouds</em></p>
<pre><code class="language-poem">the rip of wind across the face
of bugs in teeth
and tears in eyes
the ache of breathing far too hard
and the pressure of flying too fast
always rising higher to the sun
until the warmth burns
and the lungs strain
to keep breathing
the taste of lightning
the wisp of clouds all around
the caress of moisture
plummet down
racing for the ground
faster, always faster
</code></pre>
Poem - Unexpected Reduction of Memories2019-04-19T05:00:00Zhttps://d.moonfire.us/blog/2019/04/19/poem/For the nineteenth day of National Poetry Month, I wrote a poem about how telepaths view the world.
<p>For the nineteenth day of National Poetry Month, I wrote a poem about how telepaths view the world. In specific, how the group mind of Vo would create a form of poem. Their language is based on using shared memories, however art comes with the meta of memories. In this case, the presence of memories concerning a specific door.</p>
<p><em>Unexpected Reduction of Memories</em></p>
<pre><code class="language-poem">1,238,842 memories about this exact street.
1,002,248 memories about this exact house.
874,823 memories about this exact porch.
584,052 memories about this exact door.
184,823 memories about this exact handle.
9,742 memories about this exact keyhole.
92 memories about opening this exact door.
87 memories about entering this exact door.
1 memory about leaving this exact door.
</code></pre>
Two Hundred Weeks2019-04-19T05:00:00Zhttps://d.moonfire.us/blog/2019/04/19/two-hundred-weeks/About four years ago, I started posting weekly chapters. As of this week, I've been doing that for two hundred consecutive weeks.
<p>About six years ago, I was sitting in the audience at <a href="https://iowa-icon.com/">ICON</a> listening to <a href="https://craphound.com/">Cory Doctorow</a> talking about <a href="https://craphound.com/">Little Brother</a> and <a href="https://creativecommons.org/">Creative Commons</a>. I had just finished writing <a href="https://fedran.com/sand-and-blood/">Sand and Blood</a> and my first novel was about to go into the world. Even though I was hoping that <em>Sand and Blood</em> was a runaway success, I knew there was a good chance it wouldn't and the things Cory said resonated with me. In specific, the connection between Creative Commons and the various software licenses that I had used and understood for years (LGPL, MIT, Apache, etc).</p>
<p>When I actually published <em>Sand and Blood</em>, I spent a day trying to decide if I wanted to go with CC BY-NC-SA (like Cory did with <em>Little Brother</em>) or All Rights Reserved like most of the other authors I knew in the area. In the end, I didn't go with Creative Commons and put my book out with all rights. I figured once it “paid out” (money spent on the book was less than the amount I made), I'd switch it over to Creative Commons then.</p>
<p>I always hoped I'd be a great writer and people would love me right away, but that didn't happen. My skill level for marketing and self-promotion is obviously a major blind spot for me.</p>
<p>What little feedback I got pointed out that I had written something that wasn't going to be an instant classic. Hell, it wouldn't going to be a classic or even well-loved. There was usually a comment about how difficult the names were, the abusive relationships, or the fact the <a href="https://fedran.com/rutejimo/">main character</a> was most definitely <em>not</em> a hero.</p>
<p>In other words, this <a href="https://www.goodreads.com/review/show/1972507139?book_show_action=false&from_review_page=1">review</a> says it well:</p>
<blockquote>
<p>This story started out very slow, and the main character, Rutejìmo, was an intolerable dumbass who makes every wrong decision possible in every situation he finds himself in.</p>
</blockquote>
<p>I like this review for quite a few reasons. It is honest and to the point on that I set out to make Rutejìmo to be the guy <em>next</em> to the chosen one (Chimípu). Fortunately, the rest of the review made up for the brutal opening:</p>
<blockquote>
<p>Graciously, there is a turning point where the story and characters noticeably improve and finally begin to grow on you. I want to keep this review spoiler-free, but I will say that the rest of the story after the turning point more than makes up for any negativity that might have sprung up while reading the first half! It's a story of redemption, growing up, and bravery, and I enjoyed it a lot.</p>
</blockquote>
<h1>Inspiration</h1>
<p>Fast forward to ICON the next year. I'm sitting in the audience of a different room, listening to <a href="https://www.jimchines.com/">Jim C. Hines</a> and <a href="http://www.scottlynch.us/">Scott Lynch</a> talking about expectations. It was a point in my life because I gotten through many of the stages of writing and accepted that <em>Sand and Blood</em> wasn't for everyone but there were still folks out there that may love it, it was just impossible to get my book into those people's hands.</p>
<p>In that panel, one thing I came away was their suggestion:</p>
<blockquote>
<p>Write more words and don't be a dick.</p>
</blockquote>
<p>I don't know why, but that was one of the things that really pushed me to start on the new plan: to switch the license of my books over to Creative Commons and to start posting them weekly. It was my synthesis of Doctorow, Hines, and Lynch. I figured that it would eventually solve the problem Doctorow wrote about in <a href="https://craphound.com/littlebrother/about/">About <em>Little Brother</em></a>:</p>
<blockquote>
<p>For me — for pretty much every writer — the big problem isn't piracy, it’s obscurity (thanks to Tim O’Reilly for this great aphorism). Of all the people who failed to buy this book today, the majority did so because they never heard of it, not because someone gave them a free copy.</p>
</blockquote>
<h1>The Weekly Posts</h1>
<p>So I started posting <em>Sand and Blood</em> weekly. I figured I'd go with the web comic model, post it free and give the opportunity to support me if they like it. When I ran out of chapters of <em>Sand and Blood</em>, I moved into <a href="https://fedran.com/sand-and-ash/">Sand and Ash</a> and later books.</p>
<p>This week, I hit a major milestone: I've now posted two hundred consecutive chapters on my website. All of them have been in the same setting (<a href="https://fedran.com/">Fedran</a>) but they show different parts of the same world, part of my “master plan” for how my stories tie together in a world war:</p>
<ul>
<li><em>Sand and Blood</em>: 30 chapters and 69,127 words.</li>
<li><em>Sand and Ash</em>: 36 chapters and 78,803 words.</li>
<li><a href="https://fedran.com/sand-and-bone/">Sand and Bone</a>: 35 chapters and 82,749 words.</li>
<li><a href="https://fedran.com/second-hand-dresses/">Second-Hand Dresses</a>: 44 chapters and 101,045 words.</li>
<li><a href="https://fedran.com/flight-of-the-scions/">Flight of the Scions</a>: 46 chapters and 125,562 words.</li>
<li><a href="https://fedran.com/raging-alone/">Raging Alone</a>: 9 chapters and 13,852 words (so far).</li>
</ul>
<p>That comes out to 471,138 words, just shy of half a million. This is my “write more words” that I set out to do almost four years ago. I think I've done that, though probably not in the manner Jim and Scott was considering.</p>
<p>The “don't be a dick” is a little harder. Overall, I'm pretty cooperative. I'm aware of only a few cases where I've been blocked for saying stupid things (almost always stupid in my case, I spend <em>hours</em> going over what comes out of my mouth) but I don't think anything for being malicious. No idea, “being a dick” is one of those things other people have to tell me about; it isn't something I can self-evaluate.</p>
<h1>Editing</h1>
<p>Four years ago, Chuck Wendig's <a href="http://terribleminds.com/ramble/2014/02/03/slushy-glut-slog-why-the-self-publishing-shit-volcano-is-a-problem/">Shit Volcano</a> was also relatively recent in my head. That is why I've been working on getting my novels edited (two phases, one development/line and a copy editor) before I promise a novel to the front page of the <a href="https://fedran.com/">main site</a>.</p>
<p>I managed to do that with the three <em>Sand</em> novels but I haven't been able to balance the checkbook to get the other novels edited. I'm planning on that, but there are factors that prevent me from doing that for another year or so (daycare is <em>expensive</em>). I'm always working toward getting those novels edited, the versions on my site are “live” in that I tweak and fix them as I can.</p>
<h1>The Future</h1>
<p>The biggest question is where I see myself in the future. Will there be another hundred chapters? I'm planning on it. Actually, I think I've committed myself to aiming for four hundred chapters which will bring me to about ten years of working in this setting.</p>
<p>This is also the “checkpoint” that I wanted to give myself, to see if I think there is something to writing. I know writing is a long-term project, ten years might not be enough, but I'm hoping that I will get a sense of accomplishment with my writing, be it posts, likes, readers, or even <a href="https://patreon.com/dmoonfire">patrons</a>. That is why you might see me reference “this decade” when I describe my writing.</p>
<p>I'm looking forward to seeing how it turns out. There are a lot of stories I'm <a href="https://fedran.com/ideas/">considering</a>. As usual, if you are interested in my writing, consider following me on my <a href="/">website</a> or any other <a href="/contact/">social network</a> I frequent.</p>