heart: delve events generator


heart: delve events generator
01.
Overview

Delve events compatable with HEART the city beneath was a fun small project to help myself and others create delve events (think random themed challanges to encounter when traveling between locations).

Goal of this project is to streamline preparation for game or quickly get ideas for events on the fly during tabletop play when players (eventually)stray from the planned path.

02.
Details

Inspiration

Ever since getting into tabletop rpgs and coming across https://donjon.bin.sh/ in my days as budding Game Master, I've always wanted to build my own generator of sorts. One late night when preparing to run game of HEART the city beneath (table top rpg by Rowan Rook and Decard) i ran into somewhat of creative block trying to think of events between two landmarks: the Temple of the Moon Beneath and the Harvest Bazaar. The Temple had the [Religion] and [Haven] domains, and the Bazaar had [Cursed].

There are all sorts of large language models that could generate events between landmarks for you. But after giving them a go, the results came out feeling miserable and soulless.

Only if there was a tool to give random human-made events tagged with domains of each landmark, and thats when accidentally started writting my little webling using html, css, and js. and populating it with my own events (I know, I could have just come up with events for the game… but where’s the fun in that?).

Contents

I knew that i wanted contents of these events to be 100% human made so for initial version i just blasted off with my own events inspired by those in the book. They were rought around the edges but very next day i playtested it and it was great (great if somewhat unstyled app, serving great if somewhat unrefined events sleepless me wrote night before).

All of the contents are stored in json file with following properties

title: "Incense chapel", description: "<i>The air itself becomes an adversary...</i> <br> Chamber choked with ritual smoke. A small font of murky water sits neglected near the threshold. Hundreds upon hundreds of tiny dots of light penetrate the smoke, the very same incense sticks producing it. The smoke is thick enough to taste. <br><br> Those who scout will discover a small chamber to the side of main room where air is free of smoke. Going to the side chamber requires standard endurance test, crossing whole room in one go would require a hard one. Using breathing aid grants Knack on these tests.", tags: ["religion", "occult"], length: "short", author: "Awfor", link: "https://danielius.vercel.app"

The cool thing about storing the data in JSON was that I could inject it directly as HTML, which gave me the freedom to style specific parts of the text however I wanted.

Once I had my proof of concept, I contacted the game’s publishers just to let them know what I was working on and to ask if I could potentially include some official content. I heard back from them quickly to learn that they are going to do wee bit of internal show and tell for community things and include my generator in it. After that, we established what was okay and not okay to share from the official materials.

With those guidelines in place, I started fishing for more community driven delve events in places like the HEART Discord and the d100 subreddit, and got some pretty decent input from folks in those communities.

Styling

Heart is game oozing with flavour and i wanted my webling to be reflective of that. I wanted to capture burnt pages and organic tone by:

  • Custom styling al containers with bold uneven border acheved by using svg filters applied to a background which is positioned via :before. I could probably write whole article about this but in short: irregular border is achieved by combining SVG turbulance and displacement map filters:

    <feTurbulence type="fractalNoise" baseFrequency="0.05" numOctaves="4" /> <feDisplacementMap in="SourceGraphic" scale="8" />

  • Giving all elements except the title on page slight randomised tilt. very simple lil JS function:

    cards.forEach(card => { if (!card.style.transform) { // Only apply if not already tilted const randomTilt = (Math.random() - 0.5) * 3; card.style.transform = `rotate(${randomTilt}deg)`; } });

  • Carefully picking fonts to invoke the feeling i am after:

    • Eczar for bold titles

    • Crimson text for readable body text while retaining flexibility to use bold and italic variants.

    • Courier new for tags, i wanted these to feel sort of like a stamp from long lost train network.

  • Capturing a beating heart in hover states for interactive elements which used combination of noise filters similar to one used for card but cycled through different variables with this animation

    @keyframes wiggle { 0% { filter: url(#noise2); } 15% { filter: url(#noise3); } 30% { filter: url(#noise4); } 45% { filter: url(#noise2); } 100% { filter: url(#noise2); } }

And it all came together into this:

And once generated it presents us with a neat list placed below the options allowing for quick access to regeneration whilst focusing on what was generated

This design started with mobile devices in mind and very easily translates between different types of devices and screens (mobile does miss out on cool pulsing hover animation tho).

Future plans

I'm thinking of expanding this tool beyond just delve events. I've already agreed to create an interactive version of the Table of Many Tables for HEART when I get back to working on this project.