﻿<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text" xml:lang="en">Blog</title>
  <link type="application/atom+xml" href="https://mfgames.com/blog/atom.xml" rel="self" />
  <link type="text/html" href="https://mfgames.com/blog/" rel="alternate" />
  <updated>2026-03-08T17:40:43Z</updated>
  <id>https://mfgames.com/blog/</id>
  <author>
    <name>D. Moonfire</name>
  </author>
  <rights>Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</rights>
  <entry>
    <title>A Slew of (Breaking) Fixes (MfGames Writing Tools)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2026/01/17/a-slew-of-breaking-fixes/" />
    <updated>2026-01-17T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2026/01/17/a-slew-of-breaking-fixes/</id>
    <category term="mfgames-writing-tools" scheme="https://mfgames.com/categories/" label="MfGames Writing Tools" />
    <content type="html">&lt;p&gt;We've just pushed up a new version of &lt;a href="//mfgames.com/mfgames-writing-js/"&gt;mfgames-writing-js&lt;/a&gt;. Naturally, this started with the usual process of doing a little housekeeping, and bringing packages up to date.&lt;/p&gt;
&lt;p&gt;The main focus was to fix two bugs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://src.mfgames.com/mfgames-writing-js/mfgames-writing-js/issues/3"&gt;&lt;code&gt;.docx&lt;/code&gt; was generating hyphenation would caused problems with readers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://src.mfgames.com/mfgames-writing-js/mfgames-writing-js/issues/2"&gt;Using &amp;lsquo;&amp;mdash;&amp;rsquo; for section breaks fails to render breaks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://src.mfgames.com/mfgames-writing-js/mfgames-writing-js/issues/4"&gt;&lt;code&gt;.docx&lt;/code&gt; generation couldn't handle sub directories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, we had to make a breaking change and bumped the major version of some of the packages, which also requires at least a minor update to the other changes to pick up the new version ranges.&lt;/p&gt;
&lt;p&gt;And then what followed was an embarassing set of NPM package updates as we tried to get everything working consistently and feeding into dependent projects like &lt;a href="https://src.mfgames.com/nixos-contrib/fedran-writing-setup-flake"&gt;fedran-writing-setup-flake&lt;/a&gt; which is a mass setup scrip for all the writing projects on &lt;a href="//fedran.com"&gt;fedran.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Along the way, we also introduced &lt;code&gt;--log-level&lt;/code&gt; support so &lt;code&gt;mfgames-writing-format build&lt;/code&gt; wasn't quite as noisy.&lt;/p&gt;
&lt;h2&gt;Short Version&lt;/h2&gt;
&lt;p&gt;If you use &lt;code&gt;mfgames-writing-js&lt;/code&gt;, update all your packages to the latest and things should Just Work™. If they don't, please don't hesitate to &lt;a href="https://src.mfgames.com/mfgames-writing-js/mfgames-writing-js/"&gt;report an issue&lt;/a&gt; or &lt;a href="https://d.moonfire.us/contact/"&gt;contact Dulan&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Pipeline Exclusions&lt;/h2&gt;
&lt;p&gt;Added an &lt;code&gt;exclude&lt;/code&gt; to pipelines in the same pattern as the content elements:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;contents:
  - element: chapter
    source: pipeline.md
    pipeline:
      - module: &amp;quot;@mfgames-writing/hyphen-pipeline&amp;quot;
        exclude:
          editions: [docx]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This caused a difficulty with an undocumented element in &lt;code&gt;hyphen-pipeline&lt;/code&gt; which allowed for a regular expression to ignore certain words that caused problem with hyphenation. This was moved to &lt;code&gt;exclude.regex&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;contents:
  - element: chapter
    source: pipeline.md
    pipeline:
      - module: &amp;quot;@mfgames-writing/hyphen-pipeline&amp;quot;
        exclude:
          editions: [docx]
          regex: [&amp;quot;^bob$&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because this changed some projects in use, it was treated as a breaking change and bumped the version.&lt;/p&gt;
&lt;h3&gt;Section Breaks&lt;/h3&gt;
&lt;p&gt;When we write in Markdown, we always use &lt;code&gt;***&lt;/code&gt; for section breaks.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markdown"&gt;---
title: Chapter One
---

Something happened.

---

After the break.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, proejcts like &lt;a href="https://mfgames.com/mfgames-writing-setup-flake/"&gt;mfgames-writing-setup-flake&lt;/a&gt; use &lt;a href="https://prettier.io/"&gt;prettier&lt;/a&gt; which always converted the &lt;code&gt;***&lt;/code&gt; into &lt;code&gt;---&lt;/code&gt; which is also a proper Markdown rule (which we use as a section break in stories).&lt;/p&gt;
&lt;p&gt;Due to interactions with &lt;a href="https://www.npmjs.com/package/smartypants"&gt;SmartyPaths&lt;/a&gt;, those &lt;code&gt;---&lt;/code&gt; were helpfully turned into an em-dash (—). We put in a little patch code that an em-dash on a line by itself is considered a rule for section breaks and turned back into &lt;code&gt;---&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Output Directory&lt;/h2&gt;
&lt;p&gt;Another thing that we've done with &lt;code&gt;mfgames-writing-setup-flake&lt;/code&gt; is put all the output files into the &lt;code&gt;build/release&lt;/code&gt; folder to keep them out of the root directory of the repository. But there was a little but where &lt;code&gt;.docx&lt;/code&gt; files couldn't handle that.&lt;/p&gt;
&lt;p&gt;We fixed it.&lt;/p&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
&lt;p&gt;Also, it was a little annoying having so much data that we added a &lt;code&gt;--log-level&lt;/code&gt; to control output. It defaults to &lt;code&gt;info&lt;/code&gt; but can also be &lt;code&gt;trace&lt;/code&gt;, &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, and &lt;code&gt;error&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Updating Dependencies (MfGames Conventional Commit)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/12/05/updating-dependencies/" />
    <updated>2025-12-05T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/12/05/updating-dependencies/</id>
    <category term="mfgames-conventional-commit" scheme="https://mfgames.com/categories/" label="MfGames Conventional Commit" />
    <content type="html">&lt;p&gt;Just a little maintenance update.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Updated the Nix flake from 25.05 to 25.11&lt;/li&gt;
&lt;li&gt;Updated Rust to the 2025-12-05 nightly&lt;/li&gt;
&lt;li&gt;Updated various dependency packages&lt;/li&gt;
&lt;li&gt;Bumped the version to 0.3.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing really fancy, just housekeeping.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Making It Useful (MfGames Conventional Commit)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/08/12/making-it-useful/" />
    <updated>2025-08-12T05:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/08/12/making-it-useful/</id>
    <category term="mfgames-conventional-commit" scheme="https://mfgames.com/categories/" label="MfGames Conventional Commit" />
    <content type="html">&lt;p&gt;We wrote &lt;code&gt;mfgames-conventional-commits&lt;/code&gt; to solve a small itch of wanting to be able to calculate version numbers based on &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;Conventional Commits&lt;/a&gt; but only for commits that touch specific directories. That way, a change to &lt;code&gt;MfGames.IO&lt;/code&gt; would bump that version up but not touch the versioning for &lt;code&gt;MfGames.Nitride&lt;/code&gt; in the same &lt;a href="//mfgames.com/mfgames-cil/"&gt;monorepo&lt;/a&gt;. For the most part, it was to allow the CIL projects to have different versions as they all had different lineages before they were combined.&lt;/p&gt;
&lt;p&gt;As things go, we always intended to &lt;a href="https://src.mfgames.com/mfgames-git/mfgames-conventional-commit-rs/issues"&gt;polish&lt;/a&gt; and expand on the tool but other things got in the way. But then &lt;a href="//d.moonfire.us/"&gt;D. Moonfire&lt;/a&gt; was working on &lt;a href="//https://d.moonfire.us/garden/git-for-authors/"&gt;Git For Authors&lt;/a&gt; and realized they didn't have a good solution for calculating version numbers of novels. Since we already had this tool, we spent a few days making it more useful and capable for single package projects and require less overhead to configure it.&lt;/p&gt;
&lt;h2&gt;Simplified Setup&lt;/h2&gt;
&lt;p&gt;The configuration file goes into &lt;code&gt;//.config/mfgames-conventional-commit.json&lt;/code&gt; as usual, but setup has gotten significant easier. we added a &lt;code&gt;defaults&lt;/code&gt; section that applies to every project along with substitutions for packages with &lt;code&gt;{package}&lt;/code&gt; that allow each pack to have their own directories.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;$schema&amp;quot;: &amp;quot;https://mfgames.com/mfgames-conventional-commit-rs/schemas/v0.json&amp;quot;,
  &amp;quot;defaults&amp;quot;: {
    &amp;quot;tag_prefix&amp;quot;: &amp;quot;{package}-&amp;quot;,
    &amp;quot;directories&amp;quot;: { &amp;quot;include&amp;quot;: [&amp;quot;src/{package}&amp;quot;] },
    &amp;quot;files&amp;quot;: { &amp;quot;include&amp;quot;: [&amp;quot;src/{package}/**/*&amp;quot;] }
  },
  &amp;quot;packages&amp;quot;: {
    &amp;quot;MfGames.Cryptography&amp;quot;: {},
    &amp;quot;MfGames.DI.AutofacExtensions&amp;quot;: {},
    &amp;quot;MfGames.Gallium&amp;quot;: {},
    &amp;quot;MfGames.IO&amp;quot;: {},
    // There is more here
    &amp;quot;MfGames.ToolBuilder.Tables&amp;quot;: {}
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It used to be we had to have the &lt;code&gt;tag_prefix&lt;/code&gt; and &lt;code&gt;files&lt;/code&gt; elements in each one with a customization per project to include the path. Now, &lt;code&gt;{package}&lt;/code&gt; can be used to substitute the package name and defaults to apply to any package that doesn't have settings underneath itself. In the future, we'll have some configuration that will scan the &lt;code&gt;//src&lt;/code&gt; directory for the package names, but not this round.&lt;/p&gt;
&lt;h2&gt;Version Numbers&lt;/h2&gt;
&lt;p&gt;We also have two variants of version numbers based on usage. The first is the &amp;ldquo;flatten&amp;rdquo; version which calculates the most relevant major, minor, or patch version and applies it to the latest found tag. So if you have a &amp;ldquo;feat&amp;rdquo;, &amp;ldquo;fix&amp;rdquo;, &amp;ldquo;fix&amp;rdquo; on 1.0.0, it would be &amp;ldquo;1.1.0&amp;rdquo;. In contrast is the &amp;ldquo;detail&amp;rdquo; version which applies the version one at a time. So if you had the same &amp;ldquo;feat&amp;rdquo;, &amp;ldquo;fix&amp;rdquo;, &amp;ldquo;fix&amp;rdquo; on 1.0.0, the result would be &amp;ldquo;1.1.2&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Most software projects seem to make a conscious decision to bump up the version. With semantic releases, the versioning is done on the pipeline. For a long time, we used &amp;ldquo;flattened&amp;rdquo; as the basic approach since that is what &lt;a href="https://github.com/semantic-release/semantic-release#readme"&gt;Semantic Release&lt;/a&gt; did. However, with novels and the like, sometimes they go out without the pipeline running and it is useful to make sure new versions show up; hence the use of &amp;ldquo;detail&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This also resulted in a slightly different output for the &lt;code&gt;mfgames-conventional-commit version&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ cd src/MfGames.IO
$ mfgames-conventional-commit version
 package_name  last_version  flatten_version  flatten_changed  detail_version  detail_changed
 MfGames.IO    2.7.0         2.7.0            false            2.7.0           false
$ mfgames-conventional-commit version --all | head -n 5
 package_name                        last_version  flatten_version  flatten_changed  detail_version  detail_changed
 MfGames.Cryptography                14.7.0        14.7.0           false            14.7.0          false
 MfGames.DI.AutofacExtensions                      0.0.1            true             0.0.1           true
 MfGames.Gallium                     3.6.0         3.6.0            false            3.6.0           false
 MfGames.IO                          2.7.0         2.7.0            false            2.7.0           false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because we're fond of changing format as needed, so it can also dump a JSON or Markdown version. And all logging is sent to stderr, so piping can work properly.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ mfgames-conventional-commit version --json | jq
[
  {
    &amp;quot;package_name&amp;quot;: &amp;quot;MfGames.IO&amp;quot;,
    &amp;quot;last_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;flatten_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;flatten_changed&amp;quot;: false,
    &amp;quot;detail_version&amp;quot;: &amp;quot;2.7.0&amp;quot;,
    &amp;quot;detail_changed&amp;quot;: false
  }
]
$ mfgames-conventional-commit version --all --format markdown | head -n 5
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;package_name&lt;/th&gt;
&lt;th&gt;last_version&lt;/th&gt;
&lt;th&gt;flatten_version&lt;/th&gt;
&lt;th&gt;flatten_changed&lt;/th&gt;
&lt;th&gt;detail_version&lt;/th&gt;
&lt;th&gt;detail_changed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Cryptography&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;14.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.DI.AutofacExtensions&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;0.0.1&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;td&gt;0.0.1&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Gallium&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;3.6.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.IO&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;2.7.0&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MfGames.Locking&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;2.5.1&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;Another useful feature is the ability to perform updates if the version number changed. This is used to define an &lt;code&gt;updates&lt;/code&gt; element in the configuration file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;$schema&amp;quot;: &amp;quot;https://mfgames.com/mfgames-conventional-commit-rs/schemas/v0.json&amp;quot;,
  &amp;quot;defaults&amp;quot;: {
    &amp;quot;updates&amp;quot;: [
      { &amp;quot;script&amp;quot;: &amp;quot;npm version {detail_version} --no-git-tag-version&amp;quot; },
      { &amp;quot;script&amp;quot;: &amp;quot;git tag v{detail_version}&amp;quot; }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see from above, the command will change the NPM version and create a Git tag. If &lt;code&gt;always_run&lt;/code&gt; is set to true, then it will run every time it is called, otherwise it will only run if the Git tag doesn't match the calculated tag.&lt;/p&gt;
&lt;p&gt;The main reason for this is because then we don't have to write a hundred plugins for different systems. You can just write the script to do it, call another program, or just write some output. Anything a shell can do, this can do.&lt;/p&gt;
&lt;h2&gt;Inferred Package&lt;/h2&gt;
&lt;p&gt;One of the more annoying things is that we couldn't figure out the package name from the current context. For the most part, that didn't mean much since we could always provide &lt;code&gt;--package package-name&lt;/code&gt;, but we found it useful enough that we made the tool figure out the patch from the &lt;code&gt;directories&lt;/code&gt; attribute above. This also handles &lt;code&gt;{package}&lt;/code&gt; substitutions, so it is generally useful.&lt;/p&gt;
&lt;p&gt;Both the &lt;code&gt;version&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; commands also take an &lt;code&gt;--all&lt;/code&gt; which means all packages in the project instead of &lt;code&gt;--package package-name&lt;/code&gt; for an arbitrary package, or either of these to guess it from the directory.&lt;/p&gt;
&lt;h2&gt;Sane Defaults&lt;/h2&gt;
&lt;p&gt;Finally, we added a sane default if the &lt;code&gt;//.config/mfgames-conventional-commit.json&lt;/code&gt; file is missing, or it doesn't have many settings. This assumes the entire directory is a single package called &amp;ldquo;default&amp;rdquo; and it uses a &amp;ldquo;vX.X.X&amp;rdquo; tag to represent versions.&lt;/p&gt;
&lt;h2&gt;Future Steps&lt;/h2&gt;
&lt;p&gt;This is a secondary project for us. Obvious, if we have an itch and it doesn't do something we want, we'll add it. If there are any &lt;a href="https://src.mfgames.com/mfgames-git/mfgames-conventional-commit-rs/issues"&gt;issues&lt;/a&gt; that would be really useful or if you come up with something useful for the project (that is in scope), report or comment on it and we'll see about implementing it.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Introducing Fiss (Fiss)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/02/20/introducing-fiss/" />
    <updated>2025-02-20T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/02/20/introducing-fiss/</id>
    <category term="fiss" scheme="https://mfgames.com/categories/" label="Fiss" />
    <content type="html">&lt;p&gt;In a world where there are a lot of tools to manage tasks, this is one more. Fiss is a CLI-based tool that exposes issues from forges (such as &lt;a href="https://forgejo.org/"&gt;Foregejo&lt;/a&gt;) in a task-centric interface. This tool is inspired by &lt;a href="https://taskwarrior.org/"&gt;Taskwarrior&lt;/a&gt; and is designed from the ground up with the intent of using multiple forges, groups/organizations, and projects as the high-level organization.&lt;/p&gt;
&lt;h2&gt;Justification&lt;/h2&gt;
&lt;p&gt;There are a lot of tools that do the same thing, managing tasks. As well-designed or powerful as they are, the main reason for writing Fiss is that they didn't work the way we needed them too.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There Is More Than One Way To Do It&lt;/p&gt;
&lt;p&gt;&amp;mdash; Larry Wall&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fiss does, but isn't to say we haven't tried to find another alternative. We have, for many years and many attempts to find the &amp;ldquo;one perfect tool&amp;rdquo; for us.&lt;/p&gt;
&lt;h3&gt;Taskwarrior&lt;/h3&gt;
&lt;p&gt;Taskwarrior is very powerful, but it doesn't work well outside of the CLI. In our experience, the web services for sharing tasks across machines work fairly well, but are cumbersome to set up.&lt;/p&gt;
&lt;p&gt;The support on Android, our current phone operating system, is relatively poor.&lt;/p&gt;
&lt;p&gt;In many cases, the other services end up packaging Taskwarrior inside them to perform the various calculations because Taskwarrior is also very complex and not well documented. At least, it seems that way since there are not many Taskwarrior-compatible alternatives. Even the Android packages we found effectively said they packaged Taskwarrior inside them.&lt;/p&gt;
&lt;h3&gt;iCalendar&lt;/h3&gt;
&lt;p&gt;We love iCalendar (&lt;code&gt;.ics&lt;/code&gt;) files. With our local &lt;a href="https://nextcloud.com/"&gt;NextCloud&lt;/a&gt; server, it is great for handling a lot of our common tasks.&lt;/p&gt;
&lt;p&gt;Working with a Linux CLI and &lt;code&gt;.ics&lt;/code&gt; is difficult. We've tried a number of different ways over the years and haven't found anything that works the way we want. Or consistently.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Right now, this tool is barely alpha. It requires a lot of manual editing of the configuration file as documented on the &lt;a href="//mfgames.com/fiss/"&gt;website&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Adding a Server&lt;/h2&gt;
&lt;p&gt;Adding a server is pretty simple. A server has a short name, which is used by the tabular output and to reference the server.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;export FISS_SERVER=mfgames
export SERVER_URL=https://src.mfgames.com
#TOKEN=the token from Forgejo
fiss server add -s $FISS_SERVER --url $SERVER_URL --token $TOKEN
fiss server add --url $SERVER_URL --token $TOKEN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will also automatically pick up &lt;code&gt;FISS_SERVER&lt;/code&gt; from the environment. Same for &lt;code&gt;FISS_GROUP&lt;/code&gt; and &lt;code&gt;FISS_PROJECT&lt;/code&gt; below.)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;export FISS_SERVER=mfgames
fiss server add --url $SERVER_URL --token $TOKEN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can be listed, not that it helps much.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ fiss server list
 server   url                             forge    updated_seconds
 mfgames  https://src.mfgames.com/        forgejo  2025-02-15 13:15:41
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All lists can be dumped as JSON:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ fiss server list --json | jq
[
  {
    &amp;quot;server&amp;quot;: &amp;quot;mfgames&amp;quot;,
    &amp;quot;url&amp;quot;: &amp;quot;https://src.mfgames.com/&amp;quot;,
    &amp;quot;forge&amp;quot;: &amp;quot;forgejo&amp;quot;,
    &amp;quot;updated_seconds&amp;quot;: &amp;quot;2025-02-14 18:04:54&amp;quot;
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They can also be dumped as Markdown:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ fiss server list --markdown
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;server&lt;/th&gt;
&lt;th&gt;url&lt;/th&gt;
&lt;th&gt;forge&lt;/th&gt;
&lt;th&gt;updated_seconds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mfgames&lt;/td&gt;
&lt;td&gt;&lt;a href="https://src.mfgames.com/"&gt;https://src.mfgames.com/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;forgejo&lt;/td&gt;
&lt;td&gt;2025-02-14 18:04:54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The reason servers are considered first-class is that we wrote Fiss to handle multiple forges at the same time. We have multiple Forgejo instances. Eventually, this tool will be expanded to also include iCalendar, SourceHut, GitLab, and GitHub. Potentially, one could have multiples of those also, so servers are part of the organization structure.&lt;/p&gt;
&lt;h2&gt;Groups&lt;/h2&gt;
&lt;p&gt;On a server, you have groups. Right now, users don't work yet, but groups are fine.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ export FISS_GROUP=fiss
$ fiss group add -s $FISS_SERVER -g $FISS_GROUP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We decided to call the organizations and users &amp;ldquo;groups&amp;rdquo; because our &amp;ldquo;day job&amp;rdquo; uses &amp;ldquo;organizations&amp;rdquo; and it is really hard to spell that consistently while typing at speed. Using &amp;ldquo;groups&amp;rdquo; is relatively generic and is sufficient for our needs.&lt;/p&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;p&gt;Projects are the third level of organization. Creatively, they are done the same way.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ FISS_PROJECT=fiss
$ fiss project add -s $FISS_SERVER -g $FISS_GROUP -p $FISS_PROJECT
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Caching&lt;/h2&gt;
&lt;p&gt;To avoid overloading the forges, we cache the issues. In the future, we periodically will refresh the data, pick up new issues, close others. Right now, you have to manually pull in the data.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;fiss cache sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;⚠ Since there isn't a lot of elegance at this point, this will pick up all projects underneath a group and also download &lt;strong&gt;every single issue&lt;/strong&gt; from those projects. That includes closed and open. So, it would not be a good idea to point this at any project that has a large number of issues.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There is also going to be controls for automatically subscribing to new projects, so you can choose to get all of them, or only require specific ones.&lt;/p&gt;
&lt;h2&gt;Issues&lt;/h2&gt;
&lt;p&gt;Once everything is synced, then the commands are pretty simple. To list issues:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;fiss list -s $FISS_SERVER -g $FISS_GROUP -p $FISS_PROJECT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the command is run inside a Git repository (any inner directory can work, it will find the Git root), it will attempt to pick up the server, group, and project from the remotes. Also, if there is a distinct name for a project, then &lt;code&gt;-p $FISS_PROJECT&lt;/code&gt; would be sufficient.&lt;/p&gt;
&lt;p&gt;If you want to list all projects inside a Git repository, the &lt;code&gt;list&lt;/code&gt; command supports globbing for servers, groups, and slugs. This means &lt;code&gt;fiss list -p '*'&lt;/code&gt; will show all projects no matter where you are in your directory structure. Also, multiple globbing can be done with colons, such &lt;code&gt;fiss list -p fiss:mfgames-cil&lt;/code&gt; will list all &lt;code&gt;fiss&lt;/code&gt; and &lt;code&gt;mfgames-cil&lt;/code&gt; projects.&lt;/p&gt;
&lt;p&gt;From this point on, we're going to assume you are in the Git directory or have &lt;code&gt;FISS_SERVER&lt;/code&gt;, &lt;code&gt;FISS_GROUP&lt;/code&gt;, and &lt;code&gt;FISS_PROJECT&lt;/code&gt; set appropriately.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;fiss list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Creating a new issue also relatively simple and there really isn't that much. The rest of the commands are assuming you are in a Git directory, or you exported&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;$ fiss add -t &amp;quot;Name of project&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates an issue. Right now, it just says nothing but it will eventually give you a useful message or at least emit the issue number.&lt;/p&gt;
&lt;p&gt;There are commands to open and close tickets using &lt;code&gt;-i&lt;/code&gt; or &lt;code&gt;--issue&lt;/code&gt; with the issue number.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;fiss issue close -i 3
fiss issue open -i 3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;So far, even at this basic state, it is fairly functional.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sh"&gt;cd fiss
fiss list --markdown
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;title&lt;/th&gt;
&lt;th&gt;state&lt;/th&gt;
&lt;th&gt;assigned&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/6&lt;/td&gt;
&lt;td&gt;Cache foregejo API handle&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/7&lt;/td&gt;
&lt;td&gt;Refresh servers, groups, and projects periodically&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/8&lt;/td&gt;
&lt;td&gt;Show progress while syncing with server&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/9&lt;/td&gt;
&lt;td&gt;Teach &amp;lsquo;cache sync&amp;rsquo; to only sync certain projects&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/10&lt;/td&gt;
&lt;td&gt;Show information after creating a new issue&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/11&lt;/td&gt;
&lt;td&gt;Allow for &amp;ndash;body/-b to edit the body text&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/12&lt;/td&gt;
&lt;td&gt;Update to new version of foregejo API&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/13&lt;/td&gt;
&lt;td&gt;Implement subscriptions&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/14&lt;/td&gt;
&lt;td&gt;Do not show closed issues by default&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/15&lt;/td&gt;
&lt;td&gt;Do not show archived projects by default&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mfgames/fiss/fiss/16&lt;/td&gt;
&lt;td&gt;Get flake working as input for another flake&lt;/td&gt;
&lt;td&gt;open&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can also see &lt;a href="https://src.mfgames.com/fiss/fiss/issues"&gt;this list on our forge&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Future&lt;/h2&gt;
&lt;p&gt;So, we think this tool has potential. We'll be using it and improving it slowly as we find pain points or things where it doesn't work. At minimum, the goals are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add, create, and list tags on issues&lt;/li&gt;
&lt;li&gt;Implement milestones&lt;/li&gt;
&lt;li&gt;Implement sub-projects&lt;/li&gt;
&lt;li&gt;Be able to edit other elements of the item (&lt;code&gt;fiss edit -i 3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Be able to open up the page from the CLI (&lt;code&gt;fiss web -i 3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Get it working properly with NixOS flakes&lt;/li&gt;
&lt;li&gt;Be more elegant in retrieving issues&lt;/li&gt;
&lt;li&gt;Implement the subscription control so we can decide to include 100s of projects automatically&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>Moved Repository to MfGames (MfGames Writing Tools)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/01/12/moved-repository/" />
    <updated>2025-01-12T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/01/12/moved-repository/</id>
    <category term="mfgames-writing-tools" scheme="https://mfgames.com/categories/" label="MfGames Writing Tools" />
    <content type="html">&lt;p&gt;It's been a few years and this project has moved homes a few times. We realized in the last day that we haven't been paying attention to where this project was housed compared to when we abandoned GitLab because of their enshittification.&lt;/p&gt;
&lt;p&gt;The current home for &lt;code&gt;mfgames-writing-js&lt;/code&gt; is now on &lt;a href="https://src.mfgames.com/mfgames-writing-js/"&gt;src.mfgames.com&lt;/a&gt; and it now has a fancier &lt;a href="https://mfgames.com/mfgames-writing-js/"&gt;home page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are going to spend a little time spurcing up the library, bringing it to a modern version of TypeScript, and infrastructure. This will be considered a break changing since the underlying libraries have jumped significantly in version.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Updated to NixOS 25.05 (MfGames Writing Setup Flake)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/01/11/updated-to-nixos-25.05/" />
    <updated>2025-01-11T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/01/11/updated-to-nixos-25.05/</id>
    <category term="mfgames-writing-setup-flake" scheme="https://mfgames.com/categories/" label="MfGames Writing Setup Flake" />
    <content type="html">&lt;p&gt;We've updated the flake to be based off &lt;a href="https://nixos.org/blog/announcements/2025/nixos-2505/"&gt;NixOS 25.05&lt;/a&gt; and the latest version of &lt;a href="https://mfgames.com/mfgames-project-setup-flake/"&gt;mfgames-project-setup-flake&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Updated to NixOS 24.11 (MfGames Writing Setup Flake)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/01/11/updated-to-nixos-25.11/" />
    <updated>2025-01-11T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/01/11/updated-to-nixos-25.11/</id>
    <category term="mfgames-writing-setup-flake" scheme="https://mfgames.com/categories/" label="MfGames Writing Setup Flake" />
    <content type="html">&lt;p&gt;An occasional chores, we've updated the flake to be based off
&lt;a href="https://nixos.org/blog/announcements/2024/nixos-2411/"&gt;NixOS 24.11&lt;/a&gt;. From our understanding, the flake input could always be changed but this sets up a nice default using the current, non-deprecated version of NixOS.&lt;/p&gt;
&lt;p&gt;Along with this, we've also updated to the latest version of &lt;a href="https://mfgames.com/mfgames-project-setup-flake/"&gt;mfgames-project-setup-flake&lt;/a&gt; which does the same thing (and copies the same first paragraph as this post).&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Update to NixOS 24.11 (MfGames Project Setup Flake)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/01/10/update-to-nixos-24.11/" />
    <updated>2025-01-10T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/01/10/update-to-nixos-24.11/</id>
    <category term="mfgames-project-setup-flake" scheme="https://mfgames.com/categories/" label="MfGames Project Setup Flake" />
    <content type="html">&lt;p&gt;An occasional chores, we've updated the flake to be based off
&lt;a href="https://nixos.org/blog/announcements/2024/nixos-2411/"&gt;NixOS 24.11&lt;/a&gt;. From our
understanding, the flake input could always be changed but this sets up a nice
default using the current, non-deprecated version of NixOS.&lt;/p&gt;
&lt;p&gt;This came with a couple surprising changes, mostly in behavior from our tools.
In specific, &lt;code&gt;treefmt&lt;/code&gt; got a lot noisier with 24.11 when it came to unknown
files in the repository (like &lt;code&gt;.php&lt;/code&gt; files we we don't have set up).
Modifications were made to the linked &lt;code&gt;treefmt.toml&lt;/code&gt; file to not report those to
avoid a wall of text when there were a lot of them.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Update to NixOS 25.05 and more (MfGames Project Setup Flake)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2025/01/10/update-to-nixos-25.05-and-more/" />
    <updated>2025-01-10T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2025/01/10/update-to-nixos-25.05-and-more/</id>
    <category term="mfgames-project-setup-flake" scheme="https://mfgames.com/categories/" label="MfGames Project Setup Flake" />
    <content type="html">&lt;p&gt;Well, it's about time to update the flake to
&lt;a href="https://nixos.org/blog/announcements/2025/nixos-2505/"&gt;NixOS 25.05&lt;/a&gt; just for
general maintenance. There wasn't really anything special with this one, but we
did have a couple minor and one big change:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;conform&lt;/code&gt; settings did not put the scopes into the right place&lt;/li&gt;
&lt;li&gt;After experiencs, we added &lt;code&gt;.cache&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When Rust is enabled, add &lt;code&gt;target&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The other big change is we are adding
&lt;a href="//mfgames.com/mfgames-conventional-commit-rs/"&gt;mfgames-conventional-commit&lt;/a&gt; as
part of the flake. That way, we have a consistent method for updating version
numbers based on conventional commits and it plays well with the intent we have
with &lt;code&gt;conform&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Deprecating Priduck (Priduck Color Theme)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2024/12/20/deprecating-priduck/" />
    <updated>2024-12-20T06:00:00Z</updated>
    <id>https://mfgames.com/blog/2024/12/20/deprecating-priduck/</id>
    <category term="priduck-color-theme" scheme="https://mfgames.com/categories/" label="Priduck Color Theme" />
    <content type="html">&lt;p&gt;Sometimes, a path of development leads to a dead end. In this case, Priduck was written to create a more dynamic color theme based on a single color that was spread evenly around the color wheel using LCH colors.&lt;/p&gt;
&lt;p&gt;The idea was to support the bi-chromatic covers of &lt;a href="//fedran.com"&gt;Fedran&lt;/a&gt; which every point-of-view was assigned a color and it used a complementary color for accents. In our heads, it would create a striking display and would clearly identify books within a series easily.&lt;/p&gt;
&lt;p&gt;It was also too limiting. The current plan is to use a more static color scheme, in specific &lt;a href="https://www.reasonable.work/colors/"&gt;Reasonable Colors&lt;/a&gt; and allow a full gamut of colors on the book covers.&lt;/p&gt;
&lt;p&gt;That decision meant that this project doesn't make sense anymore. That isn't to say it doesn't have useful components in it, so it isn't going to be deleted from the repository.&lt;/p&gt;
&lt;p&gt;It might be resurrected in the future, it might not. We also a little vain, so if someone finds a compelling need to use these things and doesn't want to fork it (please do), then things might change.&lt;/p&gt;
&lt;p&gt;But for the time being, development on this project has ceased.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Changed the default .NET formatter (MfGames Project Setup Flake)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2024/08/07/changed-default-dotnet-formatter/" />
    <updated>2024-08-07T05:00:00Z</updated>
    <id>https://mfgames.com/blog/2024/08/07/changed-default-dotnet-formatter/</id>
    <category term="mfgames-project-setup-flake" scheme="https://mfgames.com/categories/" label="MfGames Project Setup Flake" />
    <content type="html">&lt;p&gt;When we first introduced the .NET formatter for C# files, we picked
&lt;a href="https://csharpier.com/"&gt;csharpier&lt;/a&gt; because it was a lot faster than
&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-format"&gt;dotnet format&lt;/a&gt;.
Since then, the opinionated formatting that came with &lt;code&gt;csharpier&lt;/code&gt; was getting in
the way of our style and along with conflcits with
&lt;a href="https://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The latest is breaking change that switches the default formatter out but
retains the &lt;code&gt;csharpier&lt;/code&gt; formatting for those who want it. To put it back:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-nix"&gt;config = inputs.mfgames-project-setup.lib.mkConfig {
    inherit system pkgs;
    dotnet.enable = true;
    dotnet.csharpier = true;
    dotnet.format = false; # Defaults to false, so don't need it.
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use &lt;code&gt;dotnet format&lt;/code&gt;, the setup would be:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-nix"&gt;config = inputs.mfgames-project-setup.lib.mkConfig {
    inherit system pkgs;
    dotnet.enable = true;
    dotnet.format = true;
};
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Create iCalendar Files with Nitride (MfGames .NET Libraries)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2024/06/01/nitride-icalendar/" />
    <updated>2024-06-01T05:00:00Z</updated>
    <id>https://mfgames.com/blog/2024/06/01/nitride-icalendar/</id>
    <category term="mfgames-net-libraries" scheme="https://mfgames.com/categories/" label="MfGames .NET Libraries" />
    <content type="html">&lt;p&gt;One of the more useful features in previous versions of &lt;a href="//d.moonfire.us"&gt;Dylan's&lt;/a&gt; static site generators was the ability to create an iCalendar file of the posts, both past and future. It wasn't only just to see little entries pop up for the dopamine rush, but also to give them a head's up when a new chapter for &lt;a href="//fedran.com"&gt;Fedran&lt;/a&gt; needs to be written or its been a few months since a blog post has been written.&lt;/p&gt;
&lt;p&gt;We use iCalendar because it's a solid standard format that can easily be added into Nextcloud, put on a phone, or otherwise used anywhere to keep it in mind.&lt;/p&gt;
&lt;p&gt;(Technicaly, it could also be used to create task lists for sites that are missing links or other things but out of scope for this iteration).&lt;/p&gt;
&lt;p&gt;We put this into the &lt;code&gt;MfGames.Nitride.Temporal&lt;/code&gt; even though it adds an extra dependency (&lt;a href="https://github.com/rianjs/ical.net"&gt;Ical.Net&lt;/a&gt;) because it is a relatively small feature and it hit that ratio of package management verses three additional classes. Like the rest of the temporal packages, this built to use &lt;a href="https://nodatime.org/"&gt;Noda.Time&lt;/a&gt; for coordinating times.&lt;/p&gt;
&lt;p&gt;The &lt;a href="//mfgames.com/mfgames-cil/docs/nitride/temporal/"&gt;documentation&lt;/a&gt; has some notes on how to include and use it inside a Nitride project.&lt;/p&gt;
&lt;h2&gt;New Entity Constructor&lt;/h2&gt;
&lt;p&gt;We also added new constructor to &lt;code&gt;MfGames.Gallium.Entity&lt;/code&gt; that allows multiple components to be set as part of the constructor.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// These are all the same.
var entity1 = new Entity();
entity1 = entity1.Add(&amp;quot;bob&amp;quot;);
entity1 = entity1.Add(13);

var entity2 = new Entity().Add(&amp;quot;bob&amp;quot;).Add(13);

var entity3 = new Entity().SetAll(&amp;quot;bob&amp;quot;, 13);

// These are the new features.
var entity4 = new Entity(&amp;quot;bob&amp;quot;, 13);

var entity5 = new Entity(13, &amp;quot;bob&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It seemed like a no-brainer, mainly because it is a pattern we use a lot in the code, but Dylan finds that the formatting is less than &amp;ldquo;pretty&amp;rdquo; when it comes to multi-line chaining operations.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var notPretty = new Entity(
    &amp;quot;bob&amp;quot;,
    13,
    instant,
    path)
    .AddTextContent(content);

var pretty = new Entity()
    .SetAll(
        &amp;quot;bob&amp;quot;,
        13,
        instant,
        path)
    .AddTextContent(content);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Either work though, so it will end up reducing some of the clutter for common use cases.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Refactoring Again (Priduck Color Theme)</title>
    <link rel="alternate" href="https://mfgames.com/blog/2024/05/09/refactoring-again/" />
    <updated>2024-05-09T05:00:00Z</updated>
    <id>https://mfgames.com/blog/2024/05/09/refactoring-again/</id>
    <category term="priduck-color-theme" scheme="https://mfgames.com/categories/" label="Priduck Color Theme" />
    <content type="html">&lt;p&gt;Originally, when this theme was created, it made sense to create two separate packages to provide the theme, one for the CSS files themselves and the other for a CLI to generate the source files.&lt;/p&gt;
&lt;p&gt;These we needed to generate GPL palettes for &lt;a href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; and that specific abstraction started to crumble. The result is that we merged the two Priduck repositories together and made it a single theme, with the intent that one would generate the files they want instead of a tiny package that just provided a single CSS variables version.&lt;/p&gt;
&lt;p&gt;This will also allow for the generation of character-specific stylesheets over at &lt;a href="//fedran.com"&gt;Fedran&lt;/a&gt; not to mention the book covers over there.&lt;/p&gt;
&lt;h2&gt;The CLI&lt;/h2&gt;
&lt;p&gt;The CLI is pretty simple, a verb-based Node script that installs into the &lt;code&gt;node_modules/.bin&lt;/code&gt; folder as usual:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ priduck
priduck &amp;lt;cmd&amp;gt; [args]

Commands:
  priduck css      Generate CSS files
  priduck palette  Generate palette files

Options:
  --version  Show version number                                       [boolean]
  --help     Show help                                                 [boolean]

Not enough non-option arguments: got 0, need at least 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The three basic commands are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;priduck css variables [--output /path/style.css]&lt;/code&gt; to generate the CSS variables CSS file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;priduck css mixin&lt;/code&gt; to combine CSS fragments files instead a combination of media queries and data attributes for supporting &lt;code&gt;prefers-color-scheme&lt;/code&gt; and &lt;code&gt;prefers-contrast&lt;/code&gt; options.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;priduck palette gpl --hue [--output example.gpl]&lt;/code&gt; which generates a hue-specific palette file for GNU Imp and Inkscape.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Along the process, a project can never be done if it isn't documented, so we wrote &lt;a href="/priduck-color-theme-cli-js/"&gt;some documentation&lt;/a&gt;. It gives the general gist of the tool. We'll expand on it some more &amp;ldquo;someday.&amp;rdquo;&lt;/p&gt;
</content>
  </entry>
</feed>
