diff --git a/_games/gravedigger-dark-ritual.md b/_games/gravedigger-dark-ritual.md
index 245f78c..b9393e4 100644
--- a/_games/gravedigger-dark-ritual.md
+++ b/_games/gravedigger-dark-ritual.md
@@ -5,7 +5,7 @@ coverImage: /assets/blog/gravedigger/cover.png
bannerImage: /assets/blog/gravedigger/hero.png
ogImage:
url: /assets/blog/gravedigger/cover.png
-releaseDate: "TBD"
+date: "TBD"
ctas:
- label: "Play the Prototype"
url: "https://dvdagames.itch.io/dark-ritual"
diff --git a/_projects/hex-flower-engine.md b/_projects/hex-flower-engine.md
new file mode 100644
index 0000000..704dd83
--- /dev/null
+++ b/_projects/hex-flower-engine.md
@@ -0,0 +1,24 @@
+---
+title: "Hex Flower Engine"
+excerpt: An interactive implementation of Goblin's Henchman's Hex Flower Engine in React, using the better random number generator from our TypeScript dice rolling library for rolls that are more fairly distributed.
+coverImage: /assets/blog/hex-flower-engine/hex-flower.png
+bannerImage: /assets/blog/hex-flower-engine/hex-flower.gif
+ogImage:
+ url: /assets/blog/hex-flower-engine/hex-flower.gif
+date: 2020-07-11
+ctas:
+ - label: "Run the Engine"
+ url: "https://dvdagames.github.io/react-hex-flower-engine/"
+price: "FREE"
+---
+The [Hex Flower Engine](https://goblinshenchman.wordpress.com/2018/10/25/2d6-hex-power-flower/) is an ingenious invention from [Goblin's Henchman](https://goblinshenchman.wordpress.com/) that gives Game Masters (GMs) and Dungeon Masters (DMs) a way to generate random results that are more predictable and feel more realistic than a simple table or a single die roll.
+
+> A versatile game engine using 2D6 and a 19-Hex Flower (it’s like a random table, but with a memory).
+
+It relies on rolling `2d6` (two six-sided dice) and using the results to decide which direction to move in a grid of 19 hexagons laid out in an even larger hexagon.
+
+[Goblin's Henchman has written way more than I ever could describing the various use cases for and ideas behind the engine](https://goblinshenchman.wordpress.com/category/hex-flower/), so I'll leave that to them.
+
+This particular implementation of their ideas is a simple React-based web application hosted on GitHub Pages. The code is entirely open source, so you can easily fork it to tweak to your liking, or submit an Issue or Pull Request for some feature you would like to see.
+
+This was selfishly created for my own use as a Tempest Cleric in a D&D campaign where I wanted to know if there was ever an existing storm that I could use to power up my Call Lightning spell. The DM generously created a version of the Hex Flower Engine for us to use, so I built the campaign an interactive digital version we could rely on each session.
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 167d2c0..e925b19 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -755,9 +755,9 @@
"dev": true
},
"node_modules/date-fns": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz",
- "integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
+ "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
diff --git a/public/assets/blog/hex-flower-engine/hex-flower.gif b/public/assets/blog/hex-flower-engine/hex-flower.gif
new file mode 100644
index 0000000..192eb9c
Binary files /dev/null and b/public/assets/blog/hex-flower-engine/hex-flower.gif differ
diff --git a/public/assets/blog/hex-flower-engine/hex-flower.png b/public/assets/blog/hex-flower-engine/hex-flower.png
new file mode 100644
index 0000000..3cbb8a3
Binary files /dev/null and b/public/assets/blog/hex-flower-engine/hex-flower.png differ
diff --git a/src/app/_components/date-formatter.tsx b/src/app/_components/date-formatter.tsx
index 10f7278..5b3d7ab 100644
--- a/src/app/_components/date-formatter.tsx
+++ b/src/app/_components/date-formatter.tsx
@@ -1,4 +1,4 @@
-import { parseISO, format } from "date-fns";
+import { format } from "date-fns/format";
type Props = {
dateString: string;
@@ -6,11 +6,13 @@ type Props = {
const DateFormatter = ({ dateString }: Props) => {
try {
- const date = parseISO(dateString);
+ const date = format(dateString, "yyyy-MM-dd");
- return ;
+ return ;
} catch (e) {
- return {dateString};
+ console.log("ERROR: cannot parse date");
+ console.error(e);
+ return {dateString.toString()};
}
};
diff --git a/src/app/_components/game-header.tsx b/src/app/_components/game-header.tsx
index f4cb518..55c3039 100644
--- a/src/app/_components/game-header.tsx
+++ b/src/app/_components/game-header.tsx
@@ -1,7 +1,7 @@
import CoverImage from "./cover-image";
import DateFormatter from "./date-formatter";
import { PostTitle } from "@/app/_components/post-title";
-import { CTA } from "@/interfaces/game";
+import { CTA } from "@/interfaces/cta";
type Props = {
title: string;
diff --git a/src/app/_components/game-preview.tsx b/src/app/_components/game-preview.tsx
index 4e2914f..e506519 100644
--- a/src/app/_components/game-preview.tsx
+++ b/src/app/_components/game-preview.tsx
@@ -1,5 +1,4 @@
-import { type Author } from "@/interfaces/author";
-import { type CTA } from "@/interfaces/game";
+import { type CTA } from "@/interfaces/cta";
import Link from "next/link";
import CoverImage from "./cover-image";
import DateFormatter from "./date-formatter";
diff --git a/src/app/_components/nav.tsx b/src/app/_components/nav.tsx
index a04b233..939746e 100644
--- a/src/app/_components/nav.tsx
+++ b/src/app/_components/nav.tsx
@@ -18,7 +18,9 @@ export function Nav({ includeHome = true }: NavProps): React.ReactElement {
Games
-
Projects
+
+ Projects
+
About
diff --git a/src/app/_components/project-preview.tsx b/src/app/_components/project-preview.tsx
new file mode 100644
index 0000000..d9e4d41
--- /dev/null
+++ b/src/app/_components/project-preview.tsx
@@ -0,0 +1,43 @@
+import { type CTA } from "@/interfaces/cta";
+import Link from "next/link";
+import CoverImage from "./cover-image";
+import DateFormatter from "./date-formatter";
+
+type Props = {
+ title: string;
+ coverImage: string;
+ releaseDate: string;
+ excerpt: string;
+ slug: string;
+ price: string;
+ ctas: CTA[];
+};
+
+export function ProjectPreview({ title, coverImage, releaseDate, excerpt, slug, price, ctas }: Props) {
+ return (
+