Heartstone Update 1.4: The Immersion Update

Nov 26, 2025

Update 1.4 Announcement

Hello, fellow devout followers of Mreska!

This is going to be a long one…

To celebrate the launch of InTheAttic.dev, I wanted to showcase the newest build of The Heartstone Caverns, what I am calling The Immersion Update.

The goal is to make the player feel more at home within the world of Valeria, by including responsive audio and a growing map of locations you visit. While imagination is staying the main graphics renderer, audio and spatial awareness is a core part of immersion.

The biggest systems to showcase are the map system and the audio manager, but there are some other smaller changes and fixes that make the flow of the map consistent.

There is a lot that I want to showcase in this post, as a lot of the work this update is not seen directly in the game. Let’s get into it, by first looking at:

The Audio Manager!

For a long time, the engine has been purely text-based. Today, I announce the implementation of a fully data-driven, cross-language Audio Engine.

As readers know, because our game runs on a unique stack, Python (via Pyodide) for game logic and JavaScript for the frontend, playing a simple sound wasn't so simple. Python doesn't have access to your browser's speakers, and JavaScript doesn't know when a monster has been hit.

I built a communication bridge to solve this:

While I still need to work on gathering sounds and filling them into the game, a lot of the core sound features one would expect are present.

Spells can have their own unique effects, swords and weapons can have unique hit and pick up effects, books/items can have voice over narration, combat as a whole has sfx for attack and on hit, rooms can all have their own ambient room tones, and of course all of the music.

The Options menu now includes a full suite of sliders for Master, Music, SFX volume, saving your preferences between sessions via LocalStorage.

The music is a state itself, it recognizes when you enter certain areas or encounter specific enemies. It can flow, shift, and play tracks based on what the user does in game. Further updates will add more sound and make the world feel even more lived in. One of the things I need to do is record nature soundscapes as I have fun doing that.

I wanted to add in a base amount of sounds in the 1.4 update to see how it felt to play first. I also still need to work on normalizing all of the sfx and music to be fully consistent.

The Map System

One of the biggest challenges in text adventures is spatial grounding. It’s easy to get lost in a dungeon when the world exists entirely in text. You enter a room, go north, then west, then west again, then northeast, and suddenly you aren't quite sure where the entrance was relative to where you are now.

This feature has been one of my dream additions for a while. To make the world feel more connected and to give players a sense of destination, I introduced a fully interactive, dynamic Visual World Map.

The Visual Style

I wanted a look that was akin to my backend map on Twine, but fitting the fantasy aesthetic of the game. The map uses a node-link system:

How It’s Made: The Map System

Initially, I tried to generate the map relative to the player. If you moved north, the next room was drawn at (0, -1). However, this caused a drift of sorts, where if you walked in a circle, the map would slowly warp, and rooms wouldn't line up correctly.

I switched to a Fixed Anchor System. The engine now designates a "Start Room" as the permanent (0,0) coordinate for the world. Every time you open the map, the Python backend runs a Breadth-First Search (BFS) algorithm across the entire database of rooms to calculate their absolute grid positions before sending the data to the JavaScript renderer.

Text adventures often have non-Euclidean geometry (going west might take you to a room that is 3 miles away in the world). To handle this, the map system supports Distance Modifiers.

I can tell the engine, "The path West from Dirt Road (West) is 2.2x longer than normal." The map renderer stretches that specific connection, allowing us to visualize long roads or distant towers without them overlapping the shops next door. (I was going crazy trying to get the blacksmith shop in Oakhaven not to collide with the rat cave, for instance.)

Procedural generation is great, but sometimes you just want a room right there. I implemented a coordinate override system. While the engine can auto-guess where rooms belong, I can manually "Pin" a room to specific decimal coordinates (e.g., [1.5, -4.2]) in the data files. The engine respects these pins as absolute truth and builds the rest of the procedural map around them. The auto system would be great for a game that is just a few rooms, or has teleporting rooms where it is in smaller separate chunks.

The Hidden Gem Feature

This is the feature in the update I am most proud of. To make sure the map looks perfect for my sprawling RPG, I didn't want to guess coordinates in a text file, reload the game, check the map, and repeat.

So, I built a Map Editor directly into the game engine. (Yeah, a lot of the fun stuff in this update is stuff the player doesn’t directly see. But it’s setting the stage for this engine to be used in other projects, and by other people eventually.)

This turns the game itself into the level editor, saving hours of development time. I have plans for eventually cloning this system for an item editor, maybe even a room editor. It’s really all just about breaking down the tags that are in each .json database entry and knowing which one to add or overwrite.

UI Changes

To accommodate the new map the UI has received a refinement:

Alright, enough talking! Since I am releasing this earlier than I expected, I can say with some certainty that this will not be the last update of the year. I will use the space on this site to carve out a plan of what is to come in the next update.

Overall, the immersion update completely changes the feel of exploration in The Heartstone Caverns, making the world feel larger and more connected.

I can't wait for you to try it out!

Peace and love to all, (except Big Orange and his sad turkey pardon standup routine)
Connor | YodaInTheAttic

Announcements Log