David Guerrero

engineer extraordinaire

A distorted screenshot showing examples of the comments and the comment posting UI.

I added Souls-like comments to my blog

In the Dark Souls game series, players can leave messages in the game environment. Even though the game is mainly single-player, these messages are shared online for others to find in their path.

A screenshot of the game Elden Ring displaying the messages feature. A message is being read, it says 'trap ahead' as the player faces an open tunnel.

Image credit: Windows Central.

This feature is famous as the content varies from genuine advice (trap ahead) to basic trolling (treasure chest below) and clever wordplay which I’ll let you discover.

What makes it special is the way messages are composed: they all derive from the same common list of templates (___ ahead, be wary of ___…) and words (enemy, item, castle…). There are also conjunctions (and then, or, but…) which can be used to link phrases together.

Alongside automated translations, this rigidity also greatly reduces the need for content moderation, since it’s simply not possible to write truly offensive messages.

An appraisal system allows rating each submission either good or bad, giving highly appraised messages a greater chance to be displayed.

Constrained environments like this one often bring out the best of people’s creativity. This can translate into memorable poetic or comedic moments, and of course a lot of troll messages.

It’s the same vibe that I wanted to capture for my comments system (called thoughts), and obviously avoiding content moderation as well.

Templates and words

To keep things simple, the system was distilled down to a choice of template and words to fill. Multiple lines and conjunctions are replaced by a larger choice of templates.

The initial set of templates and words was taken directly from the Elden Ring game. From that base I’ve removed some which would be irrelevant to my blog, and also added a lot of technical and corporate jargon for more exciting combinations.

I plan to keep things fresh and have a rotation for some of the words and templates over time, so please send me your suggestions!

One thing to note: no repetitions are allowed, all thoughts must be unique under each article.

Anonymity

Like in the game, all messages are undated and anonymous. Only the content matters, and whether people liked it.

Even though this all sounds straightforward, preventing spam and abuse while maintaining a good fully anonymous experience can be tricky.

If you’re interested in the technical details, you can expand the section below, or otherwise skip to the end and start sending your thoughts!

Technical details

Rate limiting

Rate limiting is implemented as multiple levels (edge/CDN, ingress, backend) with various thresholds. The most visible one is that each IP is allowed to post a single message per minute.

There’s also an invisible proof-of-work captcha using Altcha. If you’re wondering why sending a message takes a second or more, this is the reason. Your device needs to perform enough arbitrary calculations before being allowed to create a message.

This prevents basic abuse and simple scripts without getting in the way of the user experience. In case of an attack, the complexity of the task can be increased, or it could be swapped for a more complex captcha.

Limiting load

The comments are loaded asynchronously, only when getting close to the end of a page. This is achieved through an Intersection Observer, similarly to lazily loaded images.

The data is cached both at the CDN and backend level, resulting in very few requests actually hitting the Postgres database that stores all your brilliant thoughts.

Data storage

Each message or appraisal you create stores a deletion key in your local storage, so you can withdraw them at any time.

IP addresses are only stored for the rate limit evaluation duration. The backend only stores a salted hash of the author’s IP alongside each message. Some anonymous events are collected for analytics purposes (self-hosted Umami). All data is processed and stored within the EU (Hetzner/Germany).

Appraisal icon design

The most famous message in the game series is most definitely “Praise the sun!”. Since messages feature an appraisal system, I couldn’t settle for a simple thumbs-up like button, and had to capture a specific vibe.

I ended up using the same basic technique as for my logo and just drew some hands and triangles to build my own hands-raised emoji (🙌).

A side-by-side comparison between original drawings (hands and triangles), a vector traced hand and triangle, and the final appraisal logo in outlined and filled versions (two hands and three triangles in between).

Turns out fairly few vector points are needed to draw a hand!

Getting the SVG icon to work both in outlined and filled modes required some minor adjustments, but it’s all working out nicely in the end.

On doing something for fun

It’s been a while since I developed something just for fun, with no particular motive or expectations. It’s absurd, it’s useless, and I absolutely love it. Cycling through random combinations gives me great joy and I can’t wait to see what people will come up with!

So… what are your thoughts?


Thoughts from readers