Soft Thoughts after a Hard Time
Earlier this month, I took part in the 7DRL Challenge 2025 and made a game titled Soft Toy Having a Hard Time (STHaHT). It was a fairly enjoyable, if hectic, experience, and I am happy how the game turned out to be. This article is a collection of some of my thoughts surrounding STHaHT and its making.
You can play the game online on its itch.io page. You can also download the TIC-80 cartridge file, which contains the full source code and assests, from the same itch.io page.

Please note that this article reveals some hidden aspects of the game, including hidden gameplay mechanisms, and endings. You have been warned.
7DRL
I first learned about 7DRL back when I was a teenager new to Rogue-like games, shifting through RogueBasin articles to learn more about the genre, including how to make one Rogue-like myself. Back then I was unfamiliar with the game jam format and my impression of 7DRL was that it was very impressive how people can make a full game under seven days. I never succeeded in making any Rogue-like games back then, nor did I anticipate that one day I would be one of those people myself.
I joined 7DRL 2025 only because of a string of coincidences. I follow RTA in Japan, a Japanese speedrunning event similar to Games Done Quick, on Twitch. In February, another event called Mystery Dungeon RTA Fes was streamed on RTA in Japan's Twitch channel. I was in a game-making mood lately, having just published Mare Mercatus in mid-February and was working on another. Watching people play Mystery Dungeon games made me think about making a Rogue-like game myself. I remembered the existence of the 7DRL and thought that it would be a good excuse to actually execute my idea and a good oppotunity to have some publicity. So I looked up 7DRL, and found out that it would begin in my time zone less than twenty-four hours later. I shelved my ongoing project and signed up for 7DRL immediately.
Theming
I started working immediately after my time zone entered March, but ended up just making a couple of sprites before losing steam and becoming uncertain about proceeding with the game. The reason was that I did not know what to make. My initial idea for a theme was one similar to the one in the finished game: the one featuring plush creatures and evil household items. But in the earliest days of development, I was uncertain if this is actually a good theme to base my game on: I was insecure about others' perception of a quirky, childish theme.


I quickly brainstormed a couple of other possible themes and settings. The one that came the closest was "martial artist escaping after being kidnapped by bandits" set in a generic Western fantasy world, and there were also a few more Sci-Fi inspired ones. But none of them captured my heart as much as the original one. Eventually I changed my mind after asking in a group chat about whether I should go with an unconventional theme or play it safe. Those who replied all recommended that I do it my way, which was enough to convince me to settle on my original plushy-stuffy theme so I can start working on the actual game content.
I have to say I am pleasantly surprised that, after STHaHT released, I have received quite a few compliments on its theming, and I am very grateful for that.
TIC-80
STHaHT was made "on" the TIC-80 Tiny Computer, a FOSS "fantasy computer" that comes with editors for code, graphics, and sound, and is capable of running on all major platforms including the web. TIC-80's ability to target the web effortlessly was my biggest reason for choosing it. Last year I joined the Autumn Lisp Game Jam 2024 and submitted a game made using LÖVE. I was only able to distribute binaries of my game, and I felt more people would have played it should I have made it available in the browser.
I coded the STHaHT in Python, using only TIC-80's built-in editor, because it's easier to work entirely in one window, and I worry about losing data in case the TIC-80 editor and my external editor goes out of sync. Despite the editor's limited resolution and text editing capabilities, I did not feel I was been slowed down. I ended up memorizing a lot of the code snippets (so I can navigate to particular sections of my code by searching for that snippet), and felt more closely connected to my code then I would otherwise have.

As you may have noticed, the editor screenshot has the code size (in bytes) displayed on the bottom right corner. The free version of TIC-80 allows no more than 65,535 bytes of code. The "paid" version (which is free if you compile it yourself) I am using has a way higher limit, but I still tried to keep my code size under the free version limit. I would prefer my game to be playable by everyone, including those without the paid version and trapped on an operating system where they cannot set up a C++ toolchain just by installing some packages. Limiting my code size also has the additional, perhaps intended, benefit of limiting the scope of my project. So instead of fretting over whether or not to add yet another feature, I can just point at the code size and tell myself there is nothing I can do but to wrap up before I hit the limit, which actually did happen towards the end of the game jam: the finished game was less than 200 bytes away from the 65,535 bytes limit.
Level Generation
The Dungeon-of-Domesticity into which the player has fallen is not like other dungeons: it should resemble homes, not caverns, so rooms and corridors should be tightly packed together with no gap in between; a whole level (including exterior walls) should also fit into a 15 tile by 15 tile space, so the map can be displayed on the 240 pixels by 136 pixels TIC-80 screen using 8 by 8 tile and leave some space around the map to display player stats.

The constraints felt tricky but the solution was a pretty simple one: recursively divide the room in two until the room is too small to divide. This method creates no space between rooms, using the limited space efficiently, and as a bonus often generates rooms that look neatly aligned. I also added a rule to create narrow, long corridors (which would have otherwise been forbidden for being "too small"), to make the output more home-like. Once the rooms have been generated, the game selects one room to spawn the player in, and another to place the bed. It then traces a path between the rooms using DFS, and place doors between the rooms on the path to make sure the player can make it to the bed. DFS tends to find suboptimal paths that often meander around the map, forcing the player to stay longer on each level. The game then places doors to other rooms until the map is fully connected, before it finally places loots, Tellies, and monsters in the rooms.

Originally, if a room is not on the path and touches the exterior walls, it had a chance of being removed from the level. This was intended to gives levels more organic shapes as opposed to just squares. But it turned out levels always being 15 by 15 squares is actually beneficial for gameplay: the player will notice certain parts of the square missing, and direct their exploration in that direction, and they will end up finding rooms they have not previously visited. With rooms removed, however, the player does not know if a certain unvisited part of the level is a room or not, and I find it disappointing to search around a level looking for potential new rooms to only end up not finding any. It did not help that removing rooms sometimes resulted in really short and unsatisfying levels either. I ended up removing this feature entirely later in the development.
I am pretty happy with level generation as it is in the final release. However, there certainly are more things that can use some procedurally generation. I really wished that I can procedurally generate Telly programs, as playtesting the game after Telly has been implemented quickly revealed how repetitive the fixed flavour texts are. Unfortunately, at that stage, I was also running out of code space, so I could not have included it in the game.
"Tutorial"
In earlier versions of STHaHT, a "tutorial" message explaining the control scheme is displayed in the message log when the player starts a game. In later versions however the controls are permanently displayed (in dark grey text) as a part of the UI. I realized people are likely not going to remember the purpose of each key after they read it the first time, and they probably would not want to have to scroll up the message log to find the "tutorial". Showing the controls all the time do add some visual clutter, but I think the trade-off is worth it, especially considering in a game jam context most player will not spend enough time on my game to learn the controls by heart. It is like GNU Nano versus Vim. Yes, some screen space is wasted and you cannot really become a power user, but at least new users do not need to turn to StackOverflow to figure out how to quit the program.


Items
STHaHT has three classes of items: weapons, blankets (armour), and "head" items which I think are the most similar to rings in traditional Rogue-likes. Many items have hidden properties that are not explicitly explained at all in the game. For example, the Maid Headband makes you clean up dusty rooms, preventing Lint Lapins from spawning, and the Jellyfish Hat provides lighting which means you can wield a weapon more powerful than the Flashlight when inside a dark room. I have to admit that a part of the lack of explanation is laziness: I never bothered writing the flavour text for items nor the UI code to display it. But in the end I think it is more fun to let the player figure things out by themselves anyway, especially considering that STHaHT is a relatively short game where a bad decision does not cost you that much. I feel these days the player too often knows too well about video games, in no small part because every game ends up getting data-mined and documented in a "Wiki", and the joy of accidental discovery is becoming a lost art.
By the way, even though I did not choose a fantasy theming, I still included cursed items in the game. I just felt it might be a little boring if putting on a random item does not carry any risk.

The player in STHaHT has only six inventory slots, and equipping an item does not free up a slot. Initially, I set the limit for UI reasons: I want to display the whole inventory on one page so I don't have to deal with all the UI states required for pagination. I ended up having to do that anyway because I need space to display the items' (non-hidden) attributes. But the six items limit stayed because I found out that managing your inventory adds a layer of emergent gameplay. For example, one of the endings requires carrying three items that meet a certain criteria. You have to choose between this ending and the normal ending of clearing 20 levels, because when you are carrying those three items, you will likely have no space in your inventory for healing items nor head items that help you survive certain situations, which you will need if you want to survive 20 days.
My very early ideas for the game included a very different items system. Instead of providing points to attributes like attack or resistance, an item would come with properties such as "pointed", which lets you do a piercing attack, or "has wings", which lets you fly past dangers, or "has eyes" which lets you see when you are otherwise blinded. Many of the items' hidden uses are derived from these early ideas. I eventually went for a more conventional combat system instead because I did not trust myself to fully implement such an intricate system and all the possible interactions between item properties within seven days. I am content with how the items ended up working, but I do want to try my original idea out someday if I ever have a good excuse to make another Rogue-like game.
Endings
The endings were some of the last things I implemented. Before I had the endings, I could play the game, defeat monsters, get attached to items, survive, but it all felt pointlessly aimless without an ending holding the game together. I felt similarly when working on Mare Mercatus: before Mare Mercatus had level goals, it was a nice toy but eventually it felt unsatisfying to play with; but once I added goals, suddenly every dollar became meaningful, and playing it became a mentally engaging act of optimization and planning. When I was younger, I preferred sandbox-y games with no explicit goals or endings that I could theoretically play forever (although in practice this just means littering my hard drive with abandoned save files). But I have grown to appreciate closures in video games a lot more now I am older.
STHaHT has three ending conditions: the first (survive 20 days) will be told to the player in a dream on their first night. The other two show up in dreams only after the player has partially fulfilled their requirements. It is also possible to get locked out of one of the endings, in which case the player will be told in a rather scary dream. I put the ending conditions in dreams instead of front-loading them or describing them externally (i.e. in the game description on itch.io, or in a README file) because I prefer to not dump all the text on the player before they have gotten "into" the game, and I want to make the game fully self-contained and playable without referencing any external material. I am really happy with how the dreams turned out, especially how well it all fits into the game's theme and settings.

Cut Contents
-
If you look at the code, you will notice that many Telly-related variables
includes the word "
appliance
" instead of just "telly
". This is because there was originally four kind of appliances on my plan: Telly, which was the only to be implemented; Washy-Mushy, which cleans all items but comes with a risk of damaging them; Sewing Machine, which fixes all items but a pair of Safety Scissors is guaranteed to spawn on the level; and Computer, which is essentially a benign version of the Telly that cannot harm you. - I envisioned a "Mug" monster that throws itself at you and leaves broken glass on the ground when it dies. The broken glass would then damage anything that steps on it, except a player wearing a Maid Headband. I really liked the synergy here, but I never had the chance to implement it before I ran out of code space. I did make a sprite for the Mug though.
- One of the monster behaviours is "hunt", which means the monster will hunt down the player no matter where they are on the map, as opposed to "chase" where the monster only chases the player if they are in the same room. It turned out to be way more dangerous than I liked, especially considering the enemies I planned to assign this behaviour to would have shredded the player to pieces even when acting less aggressively.
- There were plans for two "mimic" type of enemies: one named "Bad", which appears as a bed until you try to sleep on it; the other are swarms of paperclips that attack you when you try to open a cabinet.
- I originally included "Cute Ribbon" and "Jester Hat" in the items, but ended up removing them because I could not think of any fitting attributes for them. Althought right now there is no item that directly boosts speed, so perhaps one of them can be repurposed for that role.
Future Plans
As I mentioned earlier, STHaHT is less than 200 bytes away from hitting the code size limit, so there isn't much space for gameplay features. But there are probably still a couple of things I can squeeze in, such as:
- Music. I actually noodled a little bit of a "melody" and the outcome stayed in the submitted version, but if you listened to it you will understand why the game does not play it. I wish to get better at composing, so I can put actual music in this game and others.
- Sound effects for things like menu operations and taking damage.
- Resurrecting one of the cancelled items, which would not require much code, just figuring out what they do.