|
| 1 | +@page "/blog/2025-12-25-year-in-review" |
| 2 | +@layout BlogPostLayout |
| 3 | + |
| 4 | +<p> |
| 5 | + 2025 was a big year for me, with significant progress across several projects. |
| 6 | + I also started new projects specifically to address problems I was running into with existing ones. |
| 7 | + Let's start by reviewing some of the work I've done for projects other than my own: |
| 8 | +</p> |
| 9 | + |
| 10 | +<section> |
| 11 | + <h3>Open Source Contributions</h3> |
| 12 | + <p> |
| 13 | + For OpenStreetMap repos, I've had 2 main contributions merge this year: |
| 14 | + </p> |
| 15 | + <ul> |
| 16 | + <li> |
| 17 | + <a href="https://github.com/osmlab/name-suggestion-index/pull/10386">Add Amegy Bank (osmlab/name-suggestion-index)</a> |
| 18 | + </li> |
| 19 | + <li> |
| 20 | + <a href="https://github.com/openstreetmap/id-tagging-schema/pull/1327">Add operator field to highway=street_lamp (openstreetmap/id-tagging-schema)</a> |
| 21 | + </li> |
| 22 | + </ul> |
| 23 | + <p> |
| 24 | + These additions improve both the ease of mapping and data quality in OpenStreetMap. |
| 25 | + </p> |
| 26 | + |
| 27 | + <p> |
| 28 | + For other repos, I've made a few contributions here and there: |
| 29 | + </p> |
| 30 | + <ul> |
| 31 | + <li> |
| 32 | + <a href="https://github.com/NginxProxyManager/nginx-proxy-manager/discussions/4598">Podman Quadlet documentation (NginxProxyManager/nginx-proxy-manager)</a> |
| 33 | + </li> |
| 34 | + <li> |
| 35 | + <a href="https://github.com/quamotion/dotnet-packaging/pull/266">.NET 10 support (quamotion/dotnet-packaging)</a> |
| 36 | + </li> |
| 37 | + <li> |
| 38 | + <a href="https://github.com/quamotion/dotnet-packaging/pull/267">Remove unsupported .NET versions (quamotion/dotnet-packaging)</a> |
| 39 | + </li> |
| 40 | + </ul> |
| 41 | + <p> |
| 42 | + The Nginx Proxy Manager documentation is very nice to have for folks that want to run the project via Podman Quadlets. |
| 43 | + Clear documentation is difficult to find for this use case, so this will help folks that want to take this route in the future. |
| 44 | + </p> |
| 45 | + <p> |
| 46 | + dotnet-packaging is a project I've been using to create the <code>.deb</code> and <code>.rpm</code> packages for my projects for a while now. |
| 47 | + This project is somewhat unmaintained, with the last change before my PR here for .NET 10 support being my PR for .NET 9 support from last year. |
| 48 | + More information on my Linux packaging journey will be below! |
| 49 | + </p> |
| 50 | +</section> |
| 51 | + |
| 52 | + |
| 53 | +<section> |
| 54 | + <h3>OpenStreetMap Contributions</h3> |
| 55 | + <p> |
| 56 | + Before getting into the state of my own projects, I also wanted to share some of the OpenStreetMap mapping projects I've been working on this year. |
| 57 | + </p> |
| 58 | + <p> |
| 59 | + Taking a look at all my changes for the year, at the time of writing this post I've made 226 changesets: |
| 60 | + </p> |
| 61 | + <img src="/images/blog/2025-12-25-year-in-review/all-osm.png" alt="All OSM Changesets 2025" /> |
| 62 | + <p> |
| 63 | + With the vast majority of my mapping being in the greater Houston area: |
| 64 | + </p> |
| 65 | + <img src="/images/blog/2025-12-25-year-in-review/greater-houston-osm.png" alt="Greater Houston OSM Changesets 2025" /> |
| 66 | + <p> |
| 67 | + And a large focus on Tomball, TX specifically: |
| 68 | + </p> |
| 69 | + <img src="/images/blog/2025-12-25-year-in-review/tomball-osm.png" alt="Tomball OSM Changesets 2025" /> |
| 70 | + <p> |
| 71 | + The main projects I've been working on this year with OSM have been: |
| 72 | + </p> |
| 73 | + <ul> |
| 74 | + <li>Landuse and POIs in Tomball, TX</li> |
| 75 | + <li>Max heights on underpasses in the Greater Houston area (<a href="https://maproulette.org/browse/challenges/53044">MapRoulette Challenge</a>)</li> |
| 76 | + <li>Shops & Amenities without an address in the Greater Houston area(<a href="https://maproulette.org/browse/challenges/53030">Shops MapRoulette Challenge</a>, <a href="https://maproulette.org/browse/challenges/53031">Amenities MapRoulette Challenge</a>)</li> |
| 77 | + <li>Roads without maxspeed in the Greater Houston area</li> |
| 78 | + </ul> |
| 79 | + <p> |
| 80 | + For that last point, I've carved out a fairly large chunk of northern Houston: |
| 81 | + </p> |
| 82 | + <img src="/images/blog/2025-12-25-year-in-review/no-maxspeed-osm.png" alt="No maxspeed OSM Changesets 2025" /> |
| 83 | + <p> |
| 84 | + This visualization was created using Overpass Turbo, with the following query: |
| 85 | + </p> |
| 86 | + <pre><code> |
| 87 | +[out:json][timeout:100]; |
| 88 | +( |
| 89 | + way ["highway"="motorway"]["access"!="no"]["access"!="private"]["motor_vehicle"!="no"][!"maxspeed"]({{bbox}}); |
| 90 | + way ["highway"="primary"]["access"!="no"]["access"!="private"]["motor_vehicle"!="no"][!"maxspeed"]({{bbox}}); |
| 91 | + way ["highway"="secondary"]["access"!="no"]["access"!="private"]["motor_vehicle"!="no"][!"maxspeed"]({{bbox}}); |
| 92 | + way ["highway"="tertiary"]["access"!="no"]["access"!="private"]["motor_vehicle"!="no"][!"maxspeed"]({{bbox}}); |
| 93 | + way ["highway"="unclassified"]["access"!="no"]["access"!="private"]["motor_vehicle"!="no"][!"maxspeed"]({{bbox}}); |
| 94 | +); |
| 95 | +out geom; |
| 96 | + |
| 97 | +{{style: |
| 98 | +node |
| 99 | +{ color:red; fill-color:red; } |
| 100 | + |
| 101 | +way |
| 102 | +{ color:red; fill-color:red; } |
| 103 | +}} |
| 104 | + </code></pre> |
| 105 | + <p> |
| 106 | + This does not include residential/neighborhood roads, and I am currently only focusing on more "main" type roads. |
| 107 | + </p> |
| 108 | + <p> |
| 109 | + The 2 mapping projects I've created MapRoulette challenges for have not seen as much movement, however I've completed about 10% of the max heights challenge so I'd call that a win still. |
| 110 | + </p> |
| 111 | +</section> |
| 112 | + |
| 113 | + |
| 114 | +<section> |
| 115 | + <h3>My projects this year</h3> |
| 116 | + |
| 117 | + <h4>BaldersGait</h4> |
| 118 | + <p> |
| 119 | + No significant progress on this project this year, this is on the backburner for now as I'd like to use Bones to plan this project out further before continuing. |
| 120 | + </p> |
| 121 | + |
| 122 | + <h4>Bones</h4> |
| 123 | + <p> |
| 124 | + At the start of the year, this project was pretty much my main focus. |
| 125 | + However throughout the year I started swapping focus to other projects as I started running into issues with dependencies that Bones relied on. |
| 126 | + </p> |
| 127 | + |
| 128 | + <h4>Questy</h4> |
| 129 | + <p> |
| 130 | + At the start of July this year, MediatR changed their license and added DRM to their project. |
| 131 | + I am very much a fan of the handler pattern that MediatR brings, so I forked the project at the last version under their Apache 2.0 license and have been maintaining it for my own use since then. |
| 132 | + </p> |
| 133 | + |
| 134 | + <h4>ReQuesty</h4> |
| 135 | + <p> |
| 136 | + In August of this year, I wanted a different way to generate HTTP Client code for the Bones API. |
| 137 | + I had been using <a href="https://github.com/RicoSuter/NSwag">nswag</a> for this previously, and it works but it definitely has some quirks to it that sometimes leads to a lot of trial and error with models to get things to generate properly. |
| 138 | + </p> |
| 139 | + <p> |
| 140 | + I found Kiota, which did not have a lot of those same issues. It just has a different massive issue: everything is generated as nullable, even when required. |
| 141 | + To me this is wrong, and so I forked Kiota to create ReQuesty, which only generates nullables when the OpenAPI spec says something is nullable. |
| 142 | + I have plans for more changes with this, but for now that was enough to make this work well for my needs. |
| 143 | + </p> |
| 144 | + <p> |
| 145 | + Most of my other changes with this were code cleanup, since it is a new project I didn't need to care about backwards compatibility nor did I care about generating for any languages other than C# so a lot of code that I did not need got ripped out. |
| 146 | + </p> |
| 147 | + |
| 148 | + <h4>Beepsky</h4> |
| 149 | + <p> |
| 150 | + At the end of November this year, I started working on Beepsky, a replacement for the Officer-Beepsky Discord bot I originally wrote in Java. |
| 151 | + This new bot is written in C# using the NetCord library, and has a couple extra features compared to the old bot. |
| 152 | + </p> |
| 153 | + <p> |
| 154 | + The most significant change is support for responding to direct @@mentions. |
| 155 | + Using an Ollama server, the bot can now generate responses when mentioned in a channel. |
| 156 | + </p> |
| 157 | + |
| 158 | + <h4>Shipyard</h4> |
| 159 | + <p> |
| 160 | + In December of this year, I started working on Shipyard, a new project to help me build and package my .NET projects for Linux distributions. |
| 161 | + This project was made to fix the issues I was running into with dotnet-packaging, with the main one being it breaking with every new .NET release. |
| 162 | + </p> |
| 163 | + <p> |
| 164 | + Instead of hooking into MSBuild and manually crafting the package archives the way dotnet-packaging does, Shipyard lets the native packaging tools handle what they do best. |
| 165 | + My main reason for letting the native tools handle the packaging is that they are well tested and maintained by the distribution maintainers, so issues like <a href="https://github.com/quamotion/dotnet-packaging/issues/99">this</a> from dotnet-packaging are no longer a worry. |
| 166 | + It's still very early days for this project, and all I have working so far is building <code>.rpm</code> packages, however here's a quick rundown of how I am envisioning this project to work: |
| 167 | + </p> |
| 168 | + <ul> |
| 169 | + <li>All packaging types will be built into the same CLI, with the packaging being driven by a single <code>shipyard.json</code> file for the project.</li> |
| 170 | + <li>This single file can drive multiple output packages, so each project ideally would only need one.</li> |
| 171 | + <li>This single file can drive multiple architectures, so you can build <code>x86_64</code> and <code>arm64</code> off the same configuration.</li> |
| 172 | + <li>The only 2 inputs the CLI should need are, <code>--config path/to/shipyard.json</code> and <code>--output path/to/output/dir/</code>.</li> |
| 173 | + </ul> |
| 174 | + |
| 175 | + <p> |
| 176 | + The steps the project currently takes for this are: |
| 177 | + </p> |
| 178 | + <ol> |
| 179 | + <li>Read and validate the provided configuration.</li> |
| 180 | + <li>Publish the .NET project for the specified runtime IDs.</li> |
| 181 | + <li>(for RPMs) Create the RPM spec file using the Scriban template.</li> |
| 182 | + <li>(for RPMs) Create the initial RPM build root with the published project files.</li> |
| 183 | + <li>(for RPMs) Optionally, include the systemd service in the build root if specified.</li> |
| 184 | + <li>(for RPMs) Use the native <code>rpmbuild</code> tool to create the RPM package.</li> |
| 185 | + <li>Copy the built package to the output directory and clean up the now unneeded intermediary build files.</li> |
| 186 | + </ol> |
| 187 | + <p> |
| 188 | + More information on this project will be coming as I continue to develop it! |
| 189 | + </p> |
| 190 | + |
| 191 | + <h4>Home</h4> |
| 192 | + <p> |
| 193 | + In July of this year I migrated this site from being built with Jekyll to being built with Blazor WASM. |
| 194 | + </p> |
| 195 | + <p> |
| 196 | + To be honest, I did this because I just really dislike JavaScript and wanted to use a better language, like C#. |
| 197 | + For a simple somewhat static site like this, Blazor WASM is definitely overkill, but I like it and it gives me another chance to learn more about this tech so I did it anyways. |
| 198 | + </p> |
| 199 | + <p> |
| 200 | + In December I also ported a couple of my smaller web games over to Blazor as well, which you can find in the Games section of the site on the left (or bottom, if you're on mobile). |
| 201 | + These were originally built for a Web Development class in college, and I really liked them so I took the time to port them to Blazor and am quite happy with the results. |
| 202 | + </p> |
| 203 | + <p> |
| 204 | + Nim hasn't changed much, it is more or less the same as it was before. |
| 205 | + But for the Voronoi generator, I was able to greatly improve performance by swapping the HTML canvas for an SVG element. |
| 206 | + The original version was an exercise in learning the canvas API for a class. |
| 207 | + For this reimplementation, I wanted a more efficient approach than looping through every pixel on the canvas to set its color. |
| 208 | + I haven't found a nice way to do this for Manhattan distance yet, so for now that remains unimplemented. |
| 209 | + </p> |
| 210 | +</section> |
| 211 | + |
| 212 | +<section> |
| 213 | + <h3>Conclusion and look into 2026</h3> |
| 214 | + <p> |
| 215 | + I am quite happy with the progress I've made this year, however there is still a lot more I want to do! |
| 216 | + </p> |
| 217 | + <p> |
| 218 | + For 2026, my main goals with my projects are going to be: |
| 219 | + </p> |
| 220 | + <ul> |
| 221 | + <li>Add <code>.deb</code> and <code>.tar.gz</code> support to Shipyard</li> |
| 222 | + <li>Port Bones from using dotnet-packaging to Shipyard</li> |
| 223 | + <li>Stabilize Bones and get to a 1.0.0 release, and start dogfooding to find where this starts breaking down in actual use</li> |
| 224 | + <li>Write more blog posts about what I'm working on, it has been 3 years since I've written anything on this blog</li> |
| 225 | + </ul> |
| 226 | + <p> |
| 227 | + Beyond that, we'll see where the year takes me. Happy holidays to those who celebrate, and I hope you have a great year ahead! |
| 228 | + </p> |
| 229 | +</section> |
0 commit comments