Guide

Building a Minecraft mod that learns from you

Dev notes on a Minecraft Fabric mod that learns from the player: counting habits, saving them with SavedData, and fixing Araz's pacing in beta.2.

In short Araz is a Fabric horror mod I made for Minecraft 26.3, 26.1.2, 1.21.10 and 1.20.1. The creature unlocks abilities by counting things the player does: 4 door uses, 5 animal visits, 3 villager encounters and 3 sleeps. Those counters are stored with the world through SavedData, so they do not reset when you leave and come back. The current release is 1.0.0-beta.2.

I develop Araz on my own. The creature does not start with a long list of moves. It starts with one ability and unlocks the others by counting what it sees the player do. Those counters are stored in the world save. As of September 2026, version 1.0.0-beta.2 supports Minecraft 26.3, 26.1.2, 1.21.10 and 1.20.1.

This is more of a build log than a pitch. I go through why the learning system works this way, where the state is saved, and what I changed in beta.2 after players told me the creature was showing up too often. The mod page is at spicesfire.com/araz if you want to see the player side.

Everything below is checkable against the mod's own MODRINTH.md and CHANGELOG.md files, which ship in the repository next to the source.

Why do horror mods stop being scary?

A stalker-style horror mod can work really well for the first few hours. Then the player learns everything the creature can do, and new encounters start feeling familiar. For me, the interesting part of the fear is not the model itself. It is not knowing what the creature might do next.

So I did not want to solve it by simply adding more behaviours. I wanted to delay the point where the player understands the whole set, and make the order depend on what that player does. Abilities are therefore tied to observation instead of time or progression. If the creature has not seen someone open a door, it cannot open one.

How the creature learns from the player

I keep one counter for each observation type and each player. When it reaches the threshold, that ability unlocks and the player gets one short chat message. The thresholds are in the mod's HIKAYE-BRIEF.md design notes and match the enum in the source.

What it watchedTimes neededWhat that unlocked
You open and close your door4Doors and glass stop being an obstacle
You walk past your animals unharmed5It can take over your animals
You walk among villagers3It can stand among them wearing a villager
You sleep3It can enter your body

Wall climbing is the only ability enabled from the start, with a threshold of zero. A new world is therefore not completely harmless. The ogrenmeHiziCarpani setting scales the other thresholds: 200 cuts the required observations in half, while 50 doubles them. The calculation happens when the value is read, so changing the setting mid-world does not alter the stored counters.

It watched you open and close your door. Doors no longer stop it.

How the learning state is saved with the world

All of it is stored in one SavedData record attached to the overworld data storage. It is serialised through a RecordCodecBuilder codec, so when something goes wrong there is one main place to inspect. The record contains:

  • Which players have already seen the one-time first sighting.
  • Per player: how many times each observation was counted, for doors, animals, villagers and sleep.
  • Per player: how many encounters happened, how many nights they survived after the first sighting, and which Corrupted Records they read.
  • Whether the abandoned camp and the portal ruin were built in this world, and the exact spot the camp was placed on.
  • Which players killed it, and which players the ruin guard threw out.

Every field after the first uses optionalFieldOf with a default. That is why 1.0.0-beta.1 worlds can still open on beta.2. If an old save does not know about geceler or kalinti_ozu, it uses the default instead of failing. It is a small thing, but it keeps an update from breaking existing worlds.

Why it appeared too often in beta.1

In beta.1 there were six different systems that could make the creature appear: ambient encounters, door and window visits, the hanging ambush, mining glimpses, abductions and bed visits. Each had its own timer. The timings looked fine when checked separately, but they all ran in the same world.

Because the timers were independent, they could stack. On a bad night four systems could fire within ten minutes, and the creature stopped feeling like a special encounter. The beta.1 feedback was not really about one feature being too frequent. It was the total number of appearances.

The beta.1 to beta.2 pacing changes

Whatbeta.1beta.2
Shared appearance cooldownnone, six separate timersone gate, 240 seconds by default
Encounter intervalabout 1.5 to 5 minutesabout 4 to 11 minutes
Familiarity discount on the wait45%30%
Hard floor on the wait1 minute4 minutes
Waiting behind a door35%18%
Watching through a window50%22%
Hanging ambush25%12%
Villager disguise40%25%
Mining glimpse per cave opening30%18%
Glimpse follow-up cooldown4 to 10 minutes8 to 18 minutes
First abductionabout 5 to 10 minutesabout 15 to 30 minutes
Later abductionsevery 7.5 to 15 minutesevery 20 to 40 minutes

The important change is the first row. Every system that can actually put the creature on screen checks the same condition first, and a visible appearance updates one shared timestamp. The other percentages are just tuning on top of that. I left things like phantom footsteps, lights going out and the ransacked chest alone because those do not spawn the creature and still help keep the world unsettling.

What four Minecraft versions and 12 languages cost

Araz currently ships for Minecraft 26.3, 26.1.2, 1.21.10 and 1.20.1. They are all Fabric builds; there is no Forge or NeoForge version. Fabric API and GeckoLib are required, while Simple Voice Chat, Mod Menu and Cloth Config are optional. In practice, keeping four versions alive means:

  • Four source trees. Against 26.1.2, the 26.3 release note lists entity types, sign text, coloured blocks and the loot number system as things that changed and had to be rewritten at every call site.
  • GeckoLib is pinned per version. The 26.3 build of Araz needs GeckoLib 5.5.6 or newer, which is a different requirement line on every store page.
  • Twelve language files of roughly 160 keys each: EN, TR, DE, ES, FR, PT-BR, RU, ZH-CN, JA, KO, PL and IT. One new line of in-game text is twelve edits.
  • Translation bugs are real bugs. The beta.2 changelog lists a wrong Altar of Araz advancement description in German and French, plus percent signs rendering incorrectly in the settings screen.
  • One store listing per version per platform, on both Modrinth and CurseForge, each with its own dependency list.

The honest version is that the 26.3 port was mostly a day of mechanical API changes with almost no gameplay work. The 1.20.1 backport was more annoying because the build chain is different too. I would still support multiple versions, but I would keep a proper API-difference note from the first port instead of writing it later.

Things that did not work

  • Six independent appearance timers. Reasonable individually, unplayable together.
  • Essence of Araz dropping only from the kill. The creature flees below half health, so a player who could not kill it could never forge The Last Line and the story stalled. In beta.2 the Essence sits in the portal ruin chest.
  • Placing the abandoned camp on the highest block of each column. That built it on treetops and on the surface of water. It now comes from the terrain generator's own height data and has to be dry and flat.
  • Checking arrival at the portal ruin by horizontal distance. Standing on the surface above it started the chase and spawned the guard 40 to 60 blocks below, inside solid rock.
  • Building the camp and the ruin only in survival mode. In creative, the coordinates the mod had just whispered pointed at plain stone.
  • Stopping the observation counters at the unlock threshold. The record signs and the Observation Log then showed capped numbers instead of real ones, which is exactly the wrong lie for a mod about being counted.
  • Shipping the 26.3 build without checking the jar contents. The spawn egg texture was missing from the mod file.

The common point in that list is that five of the seven were not really logic mistakes. The rule was correct; I just had not considered the situation it would be used in: creative mode, water, or a player standing on top of my own structure. Horror mods keep running for hours without me watching them. A lot of the bugs come from an assumption I made earlier, not from the formula itself.

What is next: Part II

The story in 1.0.0-beta.2 ends at the portal ruin. The frame is broken and the portal stays dark. That is intentional: Part I shows the door but does not take you through it. Part II is not out yet, and I am not giving it a date while beta.2 is still getting multiplayer feedback. Single player has had much more testing than multiplayer.

I publish release notes at spicesfire.com/araz/blog. The posts on this site are more about how the mod is built. If Part II has something worth documenting, I will write about that too. In game, /araz help or /araz yardim shows the available help commands.

Frequently asked questions

Which Minecraft versions does Araz support?

Araz 1.0.0-beta.2 runs on Minecraft 26.3, 26.1.2, 1.21.10 and 1.20.1. It is Fabric only; there is no Forge or NeoForge build.

Does Araz change world generation?

No. Nothing in Araz touches chunk generation. The abandoned camp and the portal ruin are built when a player gets close, so the mod is safe to add to an existing world.

What mods does Araz need to run?

Fabric API and GeckoLib are required, and the Minecraft 26.3 build needs GeckoLib 5.5.6 or newer. Simple Voice Chat, Mod Menu and Cloth Config are optional.

Does the creature still show up too often in beta.2?

It should not. Every visible appearance now passes through one shared cooldown, 240 seconds by default, instead of the six independent timers beta.1 used. If it is still too much, raise gorunmeBeklemesiSaniye in config/araz.json.

Does the creature remember me after I quit the world?

Yes. The observation counts, encounter counts, nights survived and story progress are written into the world save, so the abilities it learned from you are still unlocked when you come back.

Is Part II of the story out yet?

No. Part I ends at the portal ruin with the portal still dark, and Part II has no release date while 1.0.0-beta.2 is still collecting multiplayer reports.

Written by

Kerem Aydın Güven (SpicesFire)

I’m a web and AI developer based in Türkiye. I build Araz, SpicesFX and web products like PromtExpress and IctihatAI.

Keep reading

How-to7 min read

Porting a Fabric mod to Minecraft 26.3

What broke moving a Fabric mod from Minecraft 26.1.2 to 26.3: 56 compile errors from ten API changes, the Loom 1.18 and Gradle 9.7.1 bump, and the fixes.

← All posts