Rist
A character level beside the skills, carved into runestones you choose and deepen.
- Features
- How it works
- Installation
- The catalogue
- Configuration
- Multiplayer
- Compatibility
- Troubleshooting
- Known limitations
- Design notes
- Bug reports
- Discord
- Server
- Part of Longhouse
- Credits
Rist adds a character level beside Valheim's skills. Every level gives you a pick, and a pick carves one more rank into a runestone you choose. Vanilla skills are read and never written, rescaled or reskinned.
Built against Valheim 1.0.7, Unity 6000.0.75, BepInEx 5.4.23.5, Harmony 2.9. One DLL plus one text file, no asset bundle.
Features
- A character level with its own curve, fed by skill level-ups.
- One pick per level. Picks bank; nothing expires.
- Runestones raise a stat by a fixed amount per rank, to rank 5 by default. Every fifth rank grants a capstone, a second and different effect.
- No runestone carries a drawback.
- A panel on the compendium bar showing every runestone, what it is worth now, what the next rank adds, and which character level bought each rank.
- An experience bar on the HUD, cloned from one of the game's own bars, that flashes while a pick is unspent.
- A line above other players' heads: level, total XP, days since their last death.
- Dying no longer costs skill progress. On by default, and switchable.
- The catalogue is a plain text file. Adding a runestone is one line and no rebuild.
- On a server, progress is kept in the server's own ledger rather than in the character file.
How it works
XP and levels
XP comes from skill level-ups and from nothing else. Almost everything in Valheim raises some skill, so building, sneaking, sailing, cooking and fishing all pay in without Rist keeping a list of what counts.
A level-up is worth the skill level it reached, not a flat amount, multiplied by that skill's
weight. Vanilla's own skill cost curve is pow(level+1, 1.5), so early levels are nearly free;
a flat rate would hand out runestones in the first hours and dry up when the deep ranks start
to matter.
The weight is what stops one activity carrying the level. On the live server, a character at Rist level 12 held 1346 XP of which WoodCutting alone was 666, against 293 for everything earned in a fight. Default weights:
| Weight | Skills |
|---|---|
1 |
Swords, Knives, Clubs, Polearms, Spears, Axes, Bows, Crossbows, Unarmed, Blocking, ElementalMagic, BloodMagic |
0.5 |
Dodge, Sneak, Swim |
0.25 |
WoodCutting, Pickaxes, Crafting, Farming, Cooking, Fishing, Run, Jump, Ride |
Full price for a skill raised by something that can kill you, a fraction for repetition that
cannot. The same character comes out at level 6 under this table, with over half of it earned
fighting. SkillWeights is meant to be edited, and on a server the host's table applies to
everyone.
Cumulative XP for level N is LevelBaseXp * N^LevelExponent, which is 40 * N^1.4 by default.
Changing the weights affects new XP only. To re-price characters that already exist, change
WeightGeneration to any different text: every character is then recomputed once, on its next
login, from the skill levels the server has watched it reach. Runestones already taken are
kept, so a character re-priced from level 12 to level 6 still holds all twelve ranks and earns
no new pick until it passes level 12 again.
Spending picks
The panel is a fifth tab on the compendium bar, beside the raven and the trophy. There is no keybind; the tab is the only way in.
Each runestone carries its own outline, rock and runes, seeded off its id, so it looks the same in every session and on every machine. A rank cuts one more rune into the rim. The column beside the field follows the cursor and says what the stone is worth now, what the next rank would make it, what sits at the bottom of its track, and the character level that bought each rank.
The stones stand in five ættir, Combat, Survival, Endurance, Stealth and Utility: towers two stones wide and up to four tall, each under its name and a count of how many in it are carved. A new theme adds a tower to the right rather than a row at the bottom, so the panel grows into the width a wide screen has spare. It used to be one field a fixed number of columns across, and at twenty-one runestones it ran off the bottom of a short window.
The panel works out from the screen how to fit. On a wide or 1920x1080 screen the towers stand
with full-size stones and every tile shows its value. On a smaller one it tries smaller stones,
then lays each ætt down four wide, and only after that drops the value line from the tiles (it
stays in the column beside). It never scrolls. If a taskbar covers the bottom of the game window,
PanelBottomInset keeps that strip clear, and it stays your own setting on a server.
Death
RemoveDeathSkillLoss skips Skills.OnDeath entirely. Valheim's own world modifier is not the
same thing: Skills.OnDeath calls LowerAllSkills(m_DeathLowerFactor * Game.m_skillReductionRate),
and inside that method only the level loss is scaled by the factor.
m_level -= m_level * factor; // scaled: a zero factor means no loss
m_accumulator = 0f; // not scaled: always wiped
// ...and "$msg_skills_lowered" is shown regardless
So setting the world's skill reduction to zero still discards partial progress toward the next level in every skill, and still announces that skills were lowered. Skipping the method removes all three.
The bar and the plate
The experience bar is a clone of one of the game's own upright bars, so it carries the real frame, track and fill sprites at whatever HUD scale you run. It drains rather than snapping to empty on a level-up, and flashes while a pick is waiting. If the clone ever fails against a game update it falls back to a plain drawn bar.
The plate writes level, total XP and days since the last death into the game's own nameplate, so it inherits the plate's font, fade and distance rules. Each client publishes its own three numbers onto its own character's network object; the server cannot write them, because a write to a network object you do not own is discarded. A player without Rist shows a plain name.
Days alive counts from the day the plate first saw the character, not from the day it was created. The game keeps no creation date, so every existing character reads 0 when this first runs and grows from there. It resets on death and is counted in world days.
PlateFormat is the whole of the presentation: the fields, their order, their colours and
whether it wraps to a second line. It is a TextMeshPro label, so rich text works.
Installation
- Install BepInEx 5.4.2350. Rist uses the BepInEx 5 API and does not run on BepInEx 6.
- Install Rist from
Thunderstore or with a mod manager, or
drop
Rist.dllandcards.txtintoBepInEx\plugins\Rist.
cards.txt must sit beside the DLL. It ships with the mod and is not optional: without it no
runestone can be taken, and the startup log says NOT READY rather than ready.
Install it on the client and on the server. The server decides every number, the client reports skill-ups and applies the effects, and neither half does anything useful alone.
Longhouse Core is an optional soft dependency. See Multiplayer for what Rist gives up without it.
The catalogue
cards.txt is read once at load. Edit it and restart the game; there is no reload.
One runestone per line, eight pipe-separated fields:
id | Name | flavour text | effect | value-per-rank | capstone effect | capstone value | sigil
The last three are optional. A line with five fields is still a valid runestone.
- id is the key the ledger stores. It is permanent: change it and every rank anyone bought in that runestone is a rank in a runestone that no longer exists.
- effect is the literal name of a public float field on the game's own
SE_Stats, or one of the specials below. Valheim already sums about forty-five of these across active status effects (carry weight, armour, the six stamina costs, stealth, fall damage, regen rates, skill gain), so naming one turns it into a runestone with no code change. - value-per-rank accumulates: rank 3 of a 15-per-rank line gives 45.
- capstone effect and capstone value are granted once per
BonusEveryranks, which at the defaultMaxRank5 means once, on the final rank. A capstone can name anything an effect can, including a special. - sigil is the rune cut into the middle of the stone, written as a Latin letter. The game's rune font is a Latin-mapped decorative face, so a real runic code point renders as an empty box. Omit it and the first letter of the id is used.
Specials are effects with no SE_Stats field behind them, handled in code:
| Special | Effect |
|---|---|
*stamina:move |
Run, jump, dodge, swim and sneak all cost less |
*stamina:fight |
Attacking and blocking both cost less |
*attackspeed:melee |
Faster swings with a weapon |
*attackspeed:tools |
Faster swings with a pickaxe, axe, hammer, hoe or cultivator |
*attackspeed:ranged |
A bow reaches full draw sooner, a crossbow reloads sooner, and both fire faster |
*attackspeed:magic |
A staff casts faster. A staff firing several projectiles per cast has its burst timing sped to match; a looping staff that pays eitr once per hold stays at vanilla speed |
*damage:ranged |
More damage from bows and crossbows only. A fraction: 0.05 is 5% |
*unbroken |
A hit cannot stagger you out of a staff cast before the spell fires. A flag: write 1 |
*answer |
A perfect dodge arms your next hit on an enemy within 4 seconds. A fraction of that hit's damage |
*answer:stagger |
Chance that the answering blow staggers anything a parry would, never a boss. A fraction: 0.30 is 30% |
*lowdraw |
Seconds of a bow draw from a crouch that still count as sneaking, and the shot that ends such a draw. The character still rises to draw |
*lowdraw:silent |
Arrows loosed from a crouch make no noise where they land, so a miss does not alert the animals around it. A creature the arrow hits is still alerted by the hit. A flag: write 1 |
*sneakattack |
Raises a weapon's own sneak attack multiplier. A fraction: 0.10 is 10% more. Weapons with no sneak attack gain none |
*sneakattack:stagger |
A sneak attack on an unalerted, non-boss creature staggers it, at most once per creature per 300 seconds. A flag: write 1 |
*mead:duration |
Buff meads last longer. A fraction. Every mead except the ones that restore health, stamina or eitr, so the Lingering meads, Tonic of Ratatosk and Lightfoot Mead are included |
*mead:fullcask |
Chance a buff mead is not used up when drunk, rolled per drink. A fraction: 0.25 is 25% |
*power:cooldown |
Shortens the forsaken power's cooldown. Negative is shorter, and it cannot go below half |
*power:duration |
Seconds added to the forsaken power for every player it reaches when you cast it. A power cast by someone without it lasts the normal time for everyone. Applies to every forsaken power |
*exploreradius |
The map reveals a wider circle as you walk. A fraction: 0.05 is 5% further |
*windcone |
Narrows the sailing dead zone and turns the sail's push toward the bow inside the arc it opens, so you can sail closer to the wind. Sailing dead upwind still stalls. A fraction of the zone, capped at 0.8. Only applies to a ship you are steering, and the wind ring's dead zone narrows to match |
*rowspeed |
Rows faster, forward and back. A fraction of top rowing speed: 0.20 is 20% faster. Only applies to a ship you are steering |
*inventoryrow |
Adds rows to the player inventory grid. Not used by the default catalogue, since Valheim 1.0 sells rows from the trader, but still recognised for custom ones |
The header comment in cards.txt carries the sign conventions, which are the game's rather than
Rist's. The stamina-use modifiers are fractions where negative means cheaper, so -0.05 is a 5%
discount per rank. Four fields count from 1 rather than 0 (the three regen multipliers and
m_damageModifier); write the plain fraction and Rist adds the 1. Which fields those are is
read off a fresh SE_Stats at load rather than hardcoded, and any disagreement with the four
Rist was written against is logged.
An unknown field name or unknown special is logged and the line skipped, so a typo costs one runestone rather than the catalogue. A blank id, a duplicate id or an unparseable number is skipped the same way. An effect with no readable display name still works, and is named in the log at load so it can be added to the label table.
Configuration
BepInEx\config\ezomic.valheim.rist.cfg
BepInEx writes every entry to disk on first run and the saved value beats a new default in code. If a change appears to do nothing, check the file.
General
| Key | Default | Effect |
|---|---|---|
Enabled |
true |
Off leaves levels and runestones recorded but stops granting and applying them |
Verbose |
false |
Log every XP grant, rejection and runestone applied, plus a dump of the vanilla UI this mod clones |
ShowInfoTab |
true |
Add the runestone tab to the compendium bar. There is no keybind, so off means no way in |
Levelling
| Key | Default | Effect |
|---|---|---|
XpPerSkillLevel |
1 |
XP per skill level-up, multiplied by the level reached and the skill's weight |
LevelBaseXp |
40 |
Cumulative XP for character level 1 |
LevelExponent |
1.4 |
Cumulative XP for level N is LevelBaseXp * N^LevelExponent |
SkillWeights |
see table above | Skill=multiplier pairs, comma separated. Names are Skills.SkillType names and are case-insensitive; a raw type number also works. Negatives are clamped to zero |
DefaultSkillWeight |
1 |
What a skill not named in SkillWeights is worth |
WeightGeneration |
1 |
Change to any different text to recompute every character once, on its next login |
Cards
| Key | Default | Effect |
|---|---|---|
MaxRank |
5 |
How deep one runestone goes, and how many slots its track shows |
BonusEvery |
5 |
Ranks between capstones |
PanelBottomInset |
0 |
Pixels at the bottom of the screen the panel keeps clear, for a taskbar over the game window. About 48 clears a Windows taskbar. Stays local on a server |
AttackSpeedMax |
1 |
Ceiling on the attack-speed specials, as a fraction. 1 means a swing or cast can at most run at double speed, and a bow draw or crossbow reload can at most take half its time |
ReconcileMaxLoss |
0.34 |
How much of the ledger's runestone history may vanish from cards.txt in one go before the server refuses to reconcile at all, as a fraction of the distinct ids players hold. Server-side only |
ReconcileMaxLoss is worth understanding before you edit the catalogue. Removing a runestone
from cards.txt hands its picks back and drops the ranks bought in it, which is correct when it
was meant and is a permanent wipe when the catalogue merely failed to load. Over the threshold,
nothing is returned and nothing is removed; the server logs why on every login and leaves every
record alone until you fix the catalogue or raise this and restart. A catalogue that is missing,
unreadable or empty is refused whatever this is set to.
Death
| Key | Default | Effect |
|---|---|---|
RemoveDeathSkillLoss |
true |
Skip Skills.OnDeath, which removes the level loss, the accumulator wipe and the message together |
Gate
These bound what a client's skill-up report can be worth. Skills live on the client, so a report cannot be verified, only bounded. None of them detects a cheat, none disconnects anyone, and nothing is ever taken away. They are inert in single player.
| Key | Default | Effect |
|---|---|---|
CheckSkillBaseline |
true |
On login, take the character's skill list as the baseline this server pays from. Off also turns off MaxSkillLevelJump |
CreditExistingSkills |
true |
Pay a joining character for the skills it already has, so it arrives at the level those skills are worth with the picks to spend. Off counts only level-ups watched on this server |
MaxSkillUpsPerMinute |
30 |
Ceiling on accepted skill-up reports per player |
MaxSkillLevelJump |
1 |
Levels above the baseline a single report may claim. Raise it only if you run a mod that grants skill levels in bulk |
MaxXpPerMinute |
600 |
XP paid per player per minute of connected time. 0 or less turns it off |
XpBurst |
1800 |
How much unspent allowance banks, so an honest burst is still paid in full |
CappedMessage |
see cfg | Shown once per session, centre screen, when the earning cap withholds XP |
Crediting a joining character has a cost: a maxed vanilla character walks in at Rist level 219 with the picks to take most of the catalogue. If that matters on your server, restrict who can join rather than withholding XP. Dyrr does that.
Plate
| Key | Default | Effect |
|---|---|---|
ShowPlate |
true |
The Rist line above other players' heads. Off also stops this character publishing its own numbers |
PlateFormat |
see cfg | Tokens {lvl} {xp} {days} {name}, rich text, \n for a second line. Drop a token to drop that field |
Bar
| Key | Default | Effect |
|---|---|---|
ShowXpBar |
true |
Show the experience bar. It hides with the rest of the interface |
VanillaBar |
true |
Clone one of the game's own bars. Off draws a plain rectangle, which is also the automatic fallback if the clone fails |
BarUpright |
false |
Stand the bar on end like stamina and eitr. Off lays it flat, which is what a long bar needs |
BarFollowStamina |
true |
Place the bar relative to the stamina bar. Off falls back to BarPosX / BarPosY, as does a stamina bar that cannot be found |
BarOffsetX / BarOffsetY |
0 / 70 |
Pixels right of and below the stamina bar's centre, when following it |
BarPosX / BarPosY |
172 / 105 |
Pixels from the left edge and the bottom to the bar's centre, when not following |
BarSize |
240 |
Length in canvas units, the units vanilla sizes its own bars in. 64 is a starting stamina bar. Thickness comes from the borrowed sprite and is not settable |
BarBuildRaise |
155 |
Pixels to lift the bar while the build or ship panel is open |
BarColour |
4FB3A5 |
RRGGBB. The trailing fill is the same hue held back. E4DCC4 for bone. An unparseable value falls back to gold |
BarFlashSeconds |
4 |
How often the cloned bar pulses while a pick is waiting |
BarNoteGap |
6 |
Gap between the top of the bar and the "rist waiting" note above it |
BarX / BarBottom / BarThickness / BarLength |
168 / 75 / 10 / 60 |
Place the fallback bar only |
Every pixel number in the [Bar] block is multiplied by your HUD's canvas scale, so one value
is the same visual position on every screen. BarSize is in canvas units and is already scaled
by the game.
Multiplayer
Progress is kept on the server, in BepInEx\config\rist-ledger.txt, keyed by the platform
identity of the connection and the character being played. Valheim character files live on the
player's own disk, so nothing that decides rewards can be stored there. The client reports only
that a skill went up; every number is derived server-side.
Single player takes the same path with no special casing, and the throttles are inert there.
With Longhouse Core
Core is a soft dependency. With it installed on both ends:
- Client mod versions and build ids are checked on connect, and mismatches are rejected.
- A hash of
cards.txttravels with that check, so two ends running the same build over different catalogues are reported. - The host's Rist config is applied on connected clients, in memory only. Your own config file is not modified, and your values come back when you disconnect.
- Inventory row claims are arbitrated, so Rist and any other row-granting mod stack instead of overwriting each other.
Without Core
Rist installs and runs on its own, and solo you give up nothing. On a server you give up three things:
The catalogue is no longer checked. cards.txt names what every rank is worth, effects are
applied client-side from it, and the server only ever verifies the rank. A client that edits its
own catalogue gets whatever it wrote.
The host's curve is not applied. A client with a different LevelBaseXp reads a different
level out of the same XP, and every number on its screen disagrees with the server deciding
them. The .cfg files have to be matched by hand.
Inventory rows are claimed without an arbiter. Inventory.m_height is a single private int
with no owner, so two mods that both want rows each write it and the last writer wins. Rist's
standalone owner is correct on its own and conflicts with any other mod that grants rows, with
the winner decided by frame ordering. Install Core if you run one.
Rist logs a warning at startup when it starts without Core, naming all three.
Compatibility
- Requires BepInEx 5. Not compatible with BepInEx 6.
- 1.2.0 and later require Valheim 1.0. Earlier versions do not run on 1.0, and this one does not run on pre-1.0 Valheim.
- Conflicts with other mods that add player inventory rows unless Longhouse Core is installed. With Core, they stack.
- Vanilla skills are read and never written, so mods that change skill gain, add skills or
rebalance the skill curve work alongside this. A mod that grants skill levels in bulk will
trip
MaxSkillLevelJumpon a server; raise it. - The three attack-speed specials patch
Attack.Startand set the animator speed throughCharacterAnimEvent.Speed. Another mod driving the same number will fight over it.
Updating a server
The ledger format is v4 as of Rist 1.1.0. A v4 line does not parse on 1.0.1 or earlier and
is dropped rather than erroring, so copy rist-ledger.txt aside before updating a server you
care about. v1 to v3 lines are still read and come back as never re-priced.
Troubleshooting
A config change did nothing. BepInEx writes the whole file on first run and the saved value
wins over a new default. Edit BepInEx\config\ezomic.valheim.rist.cfg. On a server with Core
installed, the host's values are applied over yours while you are connected.
An edit to cards.txt did nothing. It is read once at load. Restart the game.
The startup log says NOT READY. cards.txt is missing, unreadable, or every line was
rejected. The warnings above that line name each rejected line. Reinstall if the file is gone:
it ships with the mod.
There is no tab on the compendium bar. Check ShowInfoTab, then look for "No compendium tab
to clone" in the log. There is no keybind, so that message means the panel has no way in and is
a bug worth reporting.
Level is 0 on a server. Check Rist is installed on the server as well as the client, and
check CreditExistingSkills.
"You are earning faster than this world will pay for." The server's earning cap is
withholding XP. MaxXpPerMinute and XpBurst control it.
The server log says it is refusing to reconcile. More of the runestone history than
ReconcileMaxLoss allows is missing from cards.txt. Nothing has been lost; fix the catalogue
or raise the setting and restart.
Known limitations
- Nothing in the runestone catalogue has been tuned against anything but reasoning and a small amount of live play. The curve has been retuned twice off real ledger data; the per-rank values have not.
- With a free choice the strongest runestone is always available, so balance rests on the
per-rank values and on
MaxRank. - The plate is published by each client onto its own character, so a modded client can put whatever it likes there. The server's ledger is still the only thing that grants a pick.
- Ranks taken before ledger
v3have no recorded level and show a dash permanently. Everything taken since is exact. SE_Statshas no max health, stamina or eitr field, since those come from food in Valheim, so no max-pool runestone is possible without a different mechanism.
Design notes
Why picks are chosen rather than dealt, why a capstone sits at the end of a track, how the bar is built out of a vanilla one, and why the ledger lives where it does: DESIGN.md.
Bug reports
The Discord is the fastest route, and the right one if you are not sure whether what you are seeing is a bug. Issues on the repo suit anything long.
Attach BepInEx\LogOutput.log, and say whether you were on a server or in single player. For a
runestone behaving wrongly, include the line from cards.txt. If a vanilla mechanic broke,
AppData\LocalLow\IronGate\Valheim\Player.log is where gameplay exceptions land, and it is a
different file from the one BepInEx writes.
Discord
discord.gg/hJzAVaZ5wb is where mod information, updates, support and bug reports go.
Server
There is a small EU server running the pack if you want somewhere to play: hard combat difficulty, resources at 1x, everything else vanilla, no application and no activity requirements. Connection details are in the Discord.
Part of Longhouse
Rist is part of Longhouse, a pinned set of the Ezomic mods that installs in one click. You do not need the pack to use Rist, and it behaves the same on its own.
Credits
Rist is an original mod by Robbin Thijssen (Thijssen Software).
Copyright (c) 2026 Robbin Thijssen. MIT licensed. See LICENSE.
Coming next
Written, not released yet. This is what the next version of Rist will carry, and it can still change.
Fixed
- The runestones sometimes showed plain letters instead of runes. Logging out to the main menu unloads the part of the game that holds the rune font, and the panel kept drawing with the font that was gone until the game was restarted. Rist now uses the game's permanent copy of its fonts, which is never unloaded, and rebuilds the panel if a font it uses disappears anyway.
- Long capstone text was cut off on the right. The lines beside a stone (now, next and capstone) wrap onto a second line instead.
Changelog
1.5.0 in Longhouse
Added
Quick chant, in Combat: staffs cast 3% faster a rank, both Elemental and Blood magic. Its capstone means a hit cannot stagger you out of a cast until the spell has left the staff, every projectile of it for a staff that fires several. Staffs that fire several projectiles per cast fire all of them at the faster speed. A looping staff that pays its eitr once per hold is not sped up, since that would be free projectiles rather than a faster cast.
discussAnswering blow, in Combat: a perfect dodge with an enemy nearby arms your next hit on an enemy for 4 seconds, 10% more damage a rank. At rank 5 that hit has a 30% chance to stagger anything a parry would, never a boss.
discussLow draw, in Stealth: drawing a bow from a crouch still counts as sneaking for the first second of the draw a rank, along with the shot itself. The game stands you up to draw and used to stop counting you as sneaking; the character still rises. At rank 5 arrows loosed from a crouch make no noise where they land, so a miss does not alert the animals around it.
discussUnseen blow, in Stealth: sneak attacks hit 10% harder a rank, with weapons that have a sneak attack. At rank 5 a sneak attack staggers the creature, once per creature every five minutes.
discussDeep draught, in Endurance: buff meads last 10% longer a rank. At rank 5 each buff mead has a 25% chance not to be used up when you drink it. It covers Fire Resistance Barley Wine, Frost and Poison Resistance Mead, Berserkir Mead, Mead of Troll Endurance, Draught of Vananidir, Brew of Animal Whispers, Tasty Mead, Anti-Sting Concoction, Love Potion, the Lingering Healing, Stamina and Eitr Meads, Tonic of Ratatosk and Lightfoot Mead. It does not cover the Minor, Medium and Major Healing Meads, the Minor and Medium Stamina Meads or the Minor Eitr Mead, which restore. A longer Lingering mead also keeps its matching potions locked out for longer.
discussOath-bound, in Utility: the forsaken power's cooldown is 5% shorter a rank. At rank 5 the blessing lasts a minute longer for everyone it reaches when you cast it, for every power. Cast by someone without it, it lasts the normal time for everyone.
discussSoft step's tile reads "detection" and Tireless's reads "move stamina", and the panel's cells and towers sit a little closer. The longest value line was widening every cell, which on a 1920x1080 screen pushed five towers off their full-size layout onto small lying stones.
discuss
Changed
Quick draw now reloads a crossbow faster too, at the same 3% a rank it draws a bow. The crossbow's reload is most of its firing cycle, and the card used to leave it alone.
discussQuick draw's capstone is bow and crossbow damage. It was 5% damage to every weapon, the same as Keen edge. A fully carved Quick draw no longer adds 5% to melee.
discuss
discussAttackSpeedMaxnow also caps how much Quick draw shortens a crossbow's reload and how fast Quick chant runs a cast, and its description in the cfg says so.
1.4.1
Changed
The rists panel sits at the top of the screen instead of in the middle, so a short field no longer floats with empty space above it.
discuss
1.4.0
Six runestones did not do what their tile said. Tireless, Long wind, Long stride and Quick draw each had a part that did nothing, and Soft step and Quiet wake made you easier to see. Your ranks are kept and now take effect.
Fixed
Soft step made you easier to see. Stealth in Valheim is a multiplier on how far away a creature spots you while you crouch, so lower is better, and Soft step added to it. A fully carved Soft step could have you seen from up to 40% further away while crouching in the dark or at a higher Sneak skill, and it never helped. It now takes 8% off that distance per rank, as the tile always claimed. Quiet wake's capstone had the same mistake and is fixed the same way. The tile now reads "sneak visibility", since "-40% stealth" would read as a loss.
discussThree running discounts did nothing. Tireless's per-rank running discount, Long wind's capstone and Long stride's capstone all changed a stat the game never reads. Sprinting is charged through a different one, and all three now use it. Tireless's capstone was already on the right stat, so it now stacks with a working 5% a rank.
discussQuick draw did not speed up drawing a bow. It sped up the release, because swing speed is the animation and a bow's draw is a timer the animation never touches. A bow now reaches full draw 3% faster per rank, and damage, arrow speed, the reticle and the bow's bend all follow. On a crossbow it still speeds up firing, not reloading.
discuss
Changed
The rists panel stands the runestones in ættir. Combat, Survival, Endurance, Stealth and Utility: towers two stones wide under a heading and a carved count, side by side. It fits the screen it is on instead of being a fixed width, so it no longer runs off the bottom of a short window, and a new ætt adds a tower to the right instead of a row. On smaller screens it tries smaller stones, then lays the ættir down, and only then drops the value line from the tiles; it never scrolls. The stone the column beside is describing now has its name in gold, and that column names its ætt.
discuss
discussPanelColumnsis gone, since the panel works out its own layout.PanelBottomInsetis new: set it if a taskbar covers the bottom of the game window. It stays your own setting on a server. An old cfg keeps thePanelColumnsline, which does nothing.The labels in the column beside the stones are 12px, up from 11.
discuss
discusscards.txtis regrouped under ætt headings, so client and server need the same build. No runestone's id changed, so every rank is kept.Weatherly's tile reads "-6% dead zone" rather than "+6% sailing into the wind", naming the black arc on the wind ring that it actually narrows.
discuss
Added
Rist warns at load if a runestone names a stat the game never reads, or gives a stat where lower is better a positive value. Both mistakes load cleanly and show a believable number on the tile, which is how these shipped.
discuss
discussAttackSpeedMaxnow also caps how much Quick draw shortens a bow's draw, and its description in the cfg says so.
1.3.1
Far sight and Weatherly did nothing in 1.3.0. They work now. Update if you carved either one; your ranks are kept and take effect.
Changed
Weatherly now makes you faster to windward. Each rank narrows the dead zone and points the sail's push toward the bow inside the arc it opens, so a fully carved card moves your best upwind heading from 52 degrees off the wind to about 36, roughly 71% faster. Dead upwind still stalls, so tacking is shallower rather than gone. It used to only narrow the zone, which did nothing you could feel: the game aims the sail's force sideways near the wind, so every heading the card opened was slower to windward than vanilla's own best.
discussWeatherly's capstone makes you row faster rather than tack faster. Rowing is a separate force from the sail, and it is what you are left doing when you still cannot point high enough. It applies forward and back.
discussWeatherly and its rowing capstone apply only to a ship you are steering, read from the helm itself, so a passenger cannot sail someone else's boat on their own runestones.
discussWith Weatherly carved, the wind ring's black dead zone narrows to match. It used to keep showing vanilla's, so the boat sailed with the wind pointer sitting in the black. The black now ends where the sail is half drawn, on both sides of the bow. Without the card the ring is untouched.
discuss
Fixed
Far sight and Weatherly did nothing in 1.3.0. Their patches were written but never registered, so no map widened, no dead zone narrowed and no boat rowed faster, and a fully carved Weatherly sailed exactly like none. Nothing failed and nothing was logged. Both work now, and Rist checks at startup for any patch that was written but never applied, and logs an error naming it. If you spent picks on either in 1.3.0, those ranks are kept and now take effect.
discussSeveral runestone values showed as raw numbers. Far sight and Weatherly read "+0.1 map sight" where they meant +5%, and Tireless's capstone read "-0.2 m_runStaminaDrainModifier", with no name and the value rounded to the wrong number. They read as percentages now, and Rist warns at load if a card's value would be shown as a raw fraction, so the next one is caught before it ships.
discuss
1.3.0
Added
Far sight and Weatherly, two runestones that widen what the world gives back rather than what you do to it. Far sight multiplies
Minimap.m_exploreRadiusby 5% a rank, so the map uncovers further as you walk, with the capstone worth another 10%. Weatherly is the sailing one:Ship.GetWindAngleFactorkills the sail inside a hard cone around dead upwind, and that cone is the only reason tacking exists, so the card puts a floor under it and lets you point nearer the wind before the sail dies. Its capstone is 20% more speed while beating upwind.Deliberately not more move speed. That card is capped at 10% from a single source because a permanent speed buff is always on, never noticed while you have it, and a player told us Rist had made his unmodded playthroughs feel worse. Neither of these follows you home: a bigger map radius is felt only on ground you have not walked, and the wind cone only at sea with a sail up. Weatherly leaves the across-the-wind term alone and is clamped so upwind can never beat a beam reach, since raising that term would just be a flat speed bonus in a hat.
discussA Rist line above other players' heads - level, total XP, and days since their last death - written into the game's own nameplate rather than drawn beside it, so it inherits the plate's font, fade and distance rules.
ShowPlateturns it off,PlateFormatis the whole of the presentation: fields, order, colours, and whether it wraps to a second line.The HUD half was one postfix. The data half is why this is more than that: nothing about another player's Rist state is on the wire, since the server pushes a record to the peer it belongs to and to nobody else. Each client now publishes its own level, XP and last-death day onto its own character's network object, which every client in range already replicates. The server cannot publish them instead - a write to a network object you do not own is discarded in silence - so a modded client can lie about its own plate. Accepted knowingly: the plate is decoration and the server's ledger still decides every pick.
Days alive counts from the day the plate first saw a character, not from its creation. The game keeps no birthday, so every existing character reads 0 on the day this ships.
discuss
1.2.2
Fixed
Quick study's capstone read "+2 m_skillLevelModifier at rank 5". The panel builds each card's green line from a table of readable names and falls back to the game's own field name when there is no entry, and
m_skillLevelModifierhad none. It is "skill levels" now, and correctly not a percentage - the game adds it to the skill's level rather than scaling it.The card itself was always working. This was the label only.
Checked against the whole catalogue rather than the one card that was reported: 25 effects are in use and this was the only one missing a name.
discuss
Changed
An effect with no readable name now says so at load, naming the card. The fallback to the raw field name is right - a card with an unnamed effect still works and still says how much it gives - but it was silent, so this sat on a player's screen for a release and was found by somebody sending a screenshot.
discussCards.Loadcross-checks every card's effect and capstone against the label table and warns once.
1.2.1
Fixed
The experience bar disappeared and never came back. It went the first time it was hidden - which on a dedicated server was immediately, before anyone saw it, and in singleplayer was the first time you died or pressed the hide-HUD key.
The bar is a clone of the eitr panel, and the eitr panel spends its life switched off for a character with no eitr: vanilla's hide clip does not fade it, it deactivates its parts by name through
AnimationObjectToggle. Everything the clone showed - frame, track, both fills, text - came from oneSetBool("Visible", true)written once when it was built. The bar was then hidden and shown withSetActive, and disabling a GameObject disables its Animator; Unity'skeepAnimatorStateOnDisabledefaults to false, so re-enabling rebinds it and resets every parameter to its authored default.Visiblewent back to false, the show clip never played again, the parts stayed inactive, and nothing re-asserted it.It is hidden by a
CanvasGroupalpha now, so nothing is ever disabled and nothing rebinds. The clone is also detached from the borrowed animator entirely at build time and brought up by hand instead - handing a permanently visible bar's visibility to a controller whose whole job is hiding the eitr panel was the mistake underneath. The flash on a waiting pick is driven here now rather than through the donor's trigger.Both
GuiBarcomponents are destroyed at build time as well, with what they point at cached first. That was the next failure waiting: this file already drives both fills by hand becauseGuiBarcachesm_barImageinAwakeand re-readsm_widthon the firstSetValue, and its comment noted thatLateUpdate"never runs, because the donor's parts are inactive". Activating those parts made it run, and it would have squashed every width tom_width * valuewith anm_widthcaptured from a donor whose fills are zero wide.Reported from the live server by a player and reproduced on two machines.
discussThe "rist waiting" note is above the bar, and follows it. It was drawn at
discussBarPosXandBarPosY, which are only where the bar is whenBarFollowStaminais off - and that has defaulted to on since the bar started following the stamina bar, so the note sat at a point the bar had long since left. It is measured off the bar's real top edge now, taken from the union of its child rects rather than the root's own, which is a thin strip that runs through the middle of what you can see.The bar no longer re-pins itself during a cutscene, when
discussHudhas parked its whole root off screen at x=10000.
Changed
Every position in the
[Bar]block is now measured against your HUD's canvas scale instead of in raw screen pixels. The bar's placement is a server setting - the host decides where it sits so that everyone on a server sees the same layout - and a raw pixel offset could not deliver that: 70 pixels below the stamina bar is a different place on a 1080p screen, a 1440p screen, and for a player running the HUD at 1.4. Multiplying by the scale factor Valheim's ownCanvasScalerapplies turns one imposed number into the same visual position on every screen. The IMGUI text scales with it too, with 12px as a floor rather than a fixed size.BarSizeis deliberately untouched: it is set in canvas units and the scaler is already applying the same factor to it.On a screen at scale 0.93 this moves the bar about five pixels; the defaults are kept as round numbers rather than retuned to cancel that out on one particular monitor.
discuss
Added
discussBarNoteGap, the gap between the top of the bar and the note above it.
1.2.0
Rebuilt for Valheim 1.0. This version does not run on pre-1.0 Valheim, and the previous one does not run on 1.0.
Changed
Which stat fields count from 1 is now read off the game rather than from a list in the mod. A fresh
discussSE_Statscarries its declared defaults, and a= 1finitialiser is exactly what "the neutral value is one" means, so the set can be asked for instead of remembered. It reproduces the same four fields today; the difference is a balance pass that makes another modifier multiplicative, which would otherwise have this writing0.03into a damage multiplier and cutting damage to 3% instead of raising it by 3%. Any disagreement with the four it was written against is logged.
1.1.1
Fixed
The plugin announced the wrong version of itself. 1.1.0 moved the csproj, the manifest and the toml and missed the
discussBepInPluginconstant, which is the version the plugin actually reports and half of what Core's gate compares - so the package read 1.1.0 on Thunderstore and introduced itself as 1.0.1 on every connection. Harmless while everyone runs identical builds, and not harmless the moment they do not.
1.1.0
XP is now weighted by which skill it came from, not only by how far that skill got.
Why
The live server's ledger asked for this rather than a hunch. A character sitting at Rist level 12 held 1346 XP, of which WoodCutting alone was 666 - half the character was felled trees, and everything earned in a fight came to 293, under a quarter of the whole. The level had stopped describing the character and started describing how long they had stood in the Meadows with an axe.
The existing weighting compounded the wrong way. XP being the level reached is right on its own, but the safest repeatable activity in the game is also the one that climbs highest, so it was collecting the most level-ups and the most XP per level-up.
Raising LevelBaseXp or LevelExponent cannot fix that, and it is the obvious reach, so it is
worth saying why not: both scale the whole curve, so the ratio survives untouched and the late
game pays for a problem that lives in the first hour. That is exactly what happened when the
pair was 60 and 1.5, and it had to be walked back.
Added
discussSkillWeights- a multiplier per skill, asSkill=multiplierpairs. The default table is built on risk: full price for a skill raised by something that can kill you, half for one that is situational, a quarter for repetition that cannot hurt you. Synced from the host, so a server sets it for everyone on it.
discussDefaultSkillWeight- what a skill not named in the table is worth.1, so a skill added by a game update or another mod is paid normally rather than silently going unpaid.
discussWeightGeneration- bump it to any different text and every character is re-priced once, on its next login, from the skill levels this server watched it reach.
Changed
Existing characters are re-priced on their next login. The bundled generation is
discuss1and no existing ledger line carries a stamp, so this happens once, automatically. The character above goes from level 12 to level 6, with 53% of it now earned fighting.Runestones already taken are kept. A character re-priced from 12 to 6 holds all twelve and earns no new pick until it passes twelve again. Refunding them would turn a re-pricing into a free rebuild of the whole character.
discussThe join-time credit is weighted by the same function as the re-pricing, deliberately shared so the two can never drift apart.
discuss
Ledger format
The ledger is now v4, carrying the generation each record was last re-priced at. v1-v3
are still read and come back as never re-priced, which is what they are.
This is a one-way door. A v4 line does not parse on 1.0.1 or earlier, which drops the
record rather than erroring, so copy rist-ledger.txt aside before updating a server you care
about.
1.0.1
Documentation and the text players read, with no change to what the mod does.
Threshold is Dyrr
The companion mod that decides who may join a world was renamed, and Rist pointed at the old
name in two places that matter: the config descriptions, which are read by anyone who opens
rist.cfg, and the notes on what Rist deliberately does not do. Both now say Dyrr.
The README is shorter
The design argument and the technical notes moved to DESIGN.md, leaving the README as what
someone reads before installing. The reasoning is all still there, one link away, rather than
in front of a reader who only wanted to know what the mod is.
Its two links are absolute now. Thunderstore builds the package page from the README alone, so
a sibling-folder path pointed at nothing there and DESIGN.md is not in the zip at all - both
would have rendered as dead links on the store page and nowhere else, which is the kind of
fault you only see after publishing.
Em-dashes are gone from the docs throughout.
1.0.0
First release. There is no 0.1.0 entry below it because 0.1.0 was never published. It was this same work under a version that had not yet been judged ready, and folding it in beats inventing a release nobody could have installed.
The line this sits on
It adds a level beside the skills. It never reads, writes, rescales or reskins a vanilla skill.
Valheim has skills but no character level. Rist adds one that runs alongside them. Vanilla skills are read and never written.
Levels and picks
Every character level earns one pick, spent on any runestone in the catalogue to raise it a rank, up to five.
discussPicks bank. Nothing expires and the panel waits.
discussNo drawbacks. A runestone is a reward or it is nothing. A cost attached to a reward makes a pick something you can regret, and regretting a permanent choice is a reason to stop playing rather than a reason to think harder.
discuss
Free choice, not a dealt hand
An earlier version dealt three runestones per level, seeded so that quitting on a bad offer and returning re-offered the same three, since otherwise the pick is theatre, since anyone can reroll until they get what they want.
Choosing freely deletes that problem rather than defending against it: no roll to reroll, no
offer to store in the ledger or on the wire, no second window with its own visibility rules.
What it costs is the tension of a hand you are dealt. A free choice means the strongest runestone
is always available, so balance now lives in the runestones themselves and in MaxRank.
The panel carries the weight for this: choosing between nineteen runestones is only a real choice if each stone says both what it is worth now and what the pick would make it.
Every fifth rank is a capstone
Taking a runestone the whole way grants something the earlier ranks did not hint at, rather than one more slice of the same number. It is what makes depth a decision against breadth instead of a rounding error: five ranks of the same small bonus is the same reward as five different small bonuses, so without this there was no reason to ever finish anything.
Capacity is a capstone, not a runestone of its own
This began as an inventory problem: late-biome kit eats the grid and leaves nothing for what you went out to fetch. The cheap fix is more rows, and that is exactly what Hoard argues against.
It was a runestone once, called Deep pack, and it was the strongest thing in the catalogue: taken first, every time, which is not a choice. A row now sits at the bottom of Ox-backed and of Sure hand, so capacity is the reward for taking a hauling runestone all the way rather than a purchase anyone makes on their first pick.
The panel
A fifth tab on the compendium bar, beside the raven and the trophy, opens a full screen of runestones, one per rist, each with its own outline, rock and marks, all seeded off the card id so a rist looks the same in every session and on every machine. A rank cuts one more mark into the rim, and the mark holds the level that bought it.
Three designs came before it: a draft window dealing three at random, a board of tiles, and that same board dressed in the game's own wooden sprites. The last is why this one exists. Borrowing a window frame is imitation, and it read as a different game no matter how close the sprites got. A runestone imitates nothing.
The bar
A fifth bar under stamina, cloned from one of the game's own so it carries the same frame, fill and trailing fill. It follows the stamina bar rather than sitting at fixed pixels, so "below stamina" stays true at any resolution and HUD scale, and it flashes while a pick is waiting.
Verdigris, because the HUD already spends red, yellow, blue and orange between its four bars and a fifth in any of those reads as one of them.
What the server decides
Reports per minute, which caps how many claims are accepted.
discussA one-level step, which caps how much a single claim may say. Skills level one at a time and fire one callback each, so a report naming a level far above the baseline this server watched that skill reach did not come from playing. This also protects the baseline, which would otherwise adopt the forged level and give every later claim an alibi.
discussXP per minute of connected time, which is the only cap that does not depend on believing the client at all. It banks three minutes so an honest burst, clearing a crypt levels four skills at once, is paid in full.
discuss
Cloning vanilla UI, and what it does not hand over
Both the bar and the compendium tab are clones of things the game already draws, which is what
makes them match. What a clone does not bring is its own lifecycle: it has never run
Awake, OnEnable or LateUpdate, because the donors sit inactive.
GuiBar puts something essential in each of those, so the bar failed three times over - the
tint reached nothing, the width was discarded and re-derived from the donor's, and setting a
value stored a number without drawing it. All three are ways of not reaching one line. The
fill is written directly now, and the trailing bar lagged by hand.
The tab had the same shape of problem read from the other end: its gold is not in any sprite
or any Image.color but in the Button's normalColor, applied to whichever graphic is its
targetGraphic. Building a layer alongside it could never match; swapping the sprite on the
graphic already being tinted inherits size, shadow, gold, hover and press at once.
The rule both arrive at: clone for geometry and sprites, drive the state yourself.
Core is optional
Rist installs and runs on its own. Core is a soft dependency; installing Rist no longer
installs Core with it, and manifest.json no longer lists it.
Solo, nothing is given up, including the extra inventory rows, which now have a Rist-owned
implementation used only when Core is absent. On a server, three things are lost, and the
README section "Core is optional, and here is exactly what that costs" sets them out: the
cards.txt hash check, the host-authoritative curve, and the arbitration of
Inventory.m_height between mods. Rist logs a warning at startup naming all three.
The row fallback deliberately copies Core's Player.Load widening rather than simplifying it.
That is not a nicety: without it every item in a granted row is destroyed by loading the game,
silently, because AddItem drops any saved position outside the current grid and the rows are
not applied until after the load. It is patched in only when Core is absent, so the two owners
can never both write the field or both widen the grid.
Mechanically, as elsewhere in the suite: every Ezomic.Core call now sits in its own
[MethodImpl(MethodImplOptions.NoInlining)] method behind a Chainloader.PluginInfos check,
because the JIT resolves a method's assemblies when it first compiles that method, and an inline
call would drag Core in before the check could prevent it. Verified by decompiling the built
DLL: Suite.* and InventoryRows.* appear only inside those isolated methods.
A character arrives worth what its skills are worth
CreditExistingSkills, on by default, pays a joining character for the skills it already
holds: turn up carrying skills worth twenty levels and you arrive at twenty levels with the
picks to spend. XP is the skill level reached, so a skill at N has already produced N(N+1)/2;
summing that over every skill is exactly what the character would hold had all of it happened
here, which also makes it safe to re-run on every login and impossible to double-pay.
Off, only XP gained on this server counts and every character starts at level 0. Config syncs from the host, so a server picks one rule for everyone on it.
There is no untrusted state. A character above the baseline was briefly marked untrusted and paid nothing "until they line up again", which it could never do, because the withholding returned before the baseline was updated, and the login check only adopted a new baseline when it had found nothing wrong, so the baseline froze while the player's real skills climbed away from it.
Keeping a well-travelled character out of a world altogether is a door policy, and the door is Dyrr's.
Known limits
Never played at the shipping curve. The pick path was exercised against a deliberately cheapened one so it could be reached without grinding.
discussLevelBaseXpandLevelExponentare back at60and1.5, and how often a stone lights up at those numbers is still a guess.Runestone balance is untested by definition. With free choice the strongest runestone is always available, and nothing has been played hard enough to find out which one that is.
discussMultiplayer has never had a second player. The version gate, config sync and catalogue hash all work host-side and against a dev server, but no remote client has connected.
discuss
Every setting · 41
All of it lives in one file, written on first run with each description beside its default. The file is the source of truth; edit it there.
BepInEx/config/ezomic.valheim.rist.cfg
server On a server, the host's value applies to everyone while they are connected; your own file is left alone and counts again when you leave. yours Keys and personal settings stay as you set them, on any server.
Bar 17
| Setting | What it does | Default | Whose |
|---|---|---|---|
| ShowXpBar | Show the experience bar beside the health bar. It hides itself with the rest of the interface, including when the HUD is hidden by hand. | true | server |
| VanillaBar | Build the bar by cloning one of the game's own upright bars, so it carries the same frame, fill sprite and trailing fill as stamina and eitr. Off draws a plain rectangle instead. That is also the automatic fallback if the clone fails, since the HUD hierarchy is scene data rather than API and can change under a game update. | true | server |
| BarUpright | Stand the bar on end like stamina and eitr. Off lays it flat, which is what a long bar needs - upright, extra length runs off the bottom of the screen. | false | server |
| BarFollowStamina | Place the bar relative to the stamina bar instead of at fixed screen pixels. Off falls back to BarPosX and BarPosY, which is also what happens if the stamina bar cannot be found. | true | server |
| BarOffsetX | Pixels right of the stamina bar's centre, when following it. | 0 | server |
| BarOffsetY | Pixels below the stamina bar's centre, when following it. | 70 | server |
| BarPosX | Distance from the left edge of the screen to the centre of the cloned bar, multiplied by your HUD's canvas scale. Only used when BarFollowStamina is off or the stamina bar cannot be found. | 172 | server |
| BarPosY | Distance from the bottom of the screen to the centre of the cloned bar, multiplied by your HUD's canvas scale - so unlike before it does NOT need re-measuring per machine. Only used when BarFollowStamina is off. | 105 | server |
| BarSize | Length of the cloned bar in canvas units, the same units vanilla sizes the stamina and eitr bars in. 64 is what a starting stamina bar measures; 240 is a bar you can read a percentage off at a glance. Thickness comes from the borrowed sprite and is not settable. | 240 | server |
| BarBuildRaise | Pixels to lift the cloned bar while the build or ship panel is open. Vanilla moves its own bars up by the same amount to clear that panel; ours is pinned in screen space, so it has to make the move by hand. | 155 | server |
| BarColour | Bar colour as RRGGBB hex. The trailing fill is the same hue held back, the way vanilla tells its bar pairs apart. Unparseable values fall back to gold. Verdigris - aged bronze. Picked from a five-way comparison against the bars already on the HUD, which spend red, yellow, blue and orange between them, so a fifth in any of those reads as one of them. It is cool like eitr but far enough round the wheel never to be taken for it, and it suits a Norse metal palette in a way the green it replaced did not: a green bar reads as health or poison from habit, whatever it is measuring. Bone is E4DCC4 if you would rather have pale stone. That was the original choice and it was never actually seen - for a long time no value here reached the fill at all, and the bar simply showed the eitr donor's own purple. | 4FB3A5 | server |
| BarFlashSeconds | How often the bar pulses while a pick is waiting to be spent, in seconds. Only applies to the cloned bar. | 4 | server |
| BarNoteGap | Gap between the top of the bar and the 'rist waiting' note above it. Measured from the bar's own top edge rather than from a fixed screen position, so it follows the bar when the build panel shoves it upward. Like every pixel number here it is multiplied by your HUD's canvas scale, so one value is the same gap on every screen. | 6 | server |
| BarX | Pixels from the left edge of the screen to the left edge of the bar. The default aims to sit just right of the health bar. | 168 | server |
| BarBottom | Pixels from the bottom of the screen to the bottom of the bar. Depends on your resolution and HUD scale, so it will probably need nudging once. | 75 | server |
| BarThickness | Bar thickness in pixels. | 10 | server |
| BarLength | Bar height in pixels. | 60 | server |
Cards 5
| Setting | What it does | Default | Whose |
|---|---|---|---|
| BonusEvery | Ranks between capstones. A card that names a bonus effect in its last two cards.txt fields grants it once per this many ranks. At the default MaxRank of 5 that means once, on the final upgrade. | 5 | server |
| ReconcileMaxLoss | How much of the ledger's card history may vanish from cards.txt in one go before Rist refuses to reconcile at all, as a fraction of the distinct card ids players actually hold. A third, because a pack or two being retired is a normal edit and losing half of what everyone is carrying is not. Over this, nothing is returned and nothing is removed: the server logs why on every login and leaves every record untouched until you either fix the catalogue or raise this and restart. Stranded picks are recoverable, a deleted history is not. Judged once, when the ledger is read. A catalogue that is missing, unreadable or empty is refused whatever this says - there is no edit that legitimately empties it, so 1 does not disable that half. Server-side only; the ledger exists nowhere else. | 0.34 | server |
| AttackSpeedMax | Ceiling on the attack-speed cards, as a fraction. 1 means a swing or cast animation can at most run at double speed, a bow can at most draw in half its time, and a crossbow can at most reload in half its time. A staff that fires several projectiles per cast has its burst spacing shortened by the same capped amount, so its last bursts still land inside the faster cast. On a swing this multiplies an animation rather than a number in a table, and animation events are what land the hit, so a mis-typed catalogue line could otherwise run the whole character at twenty times speed. On a bow or crossbow it divides the draw or reload time, so the same typo would make every shot instant. | 1 | server |
| PanelBottomInset | Pixels kept clear at the bottom of the screen when the rists panel works out how to fit. Raise it if a taskbar or overlay covers the bottom of the game window and hides the last row of stones; around 48 clears a Windows taskbar. The panel picks the richest layout that fits what is left - full tiles first, standing and then lying, at 100px stones and then 78; then tiles without their value line - so a larger inset trades size for being fully visible. Your own setting even on a server: it is about your window, not a rule. | 0 | yours |
| MaxRank | How deep a single card can be taken. A card at this rank stops being pickable, and is also how many slots its track shows. | 5 | server |
Death 1
| Setting | What it does | Default | Whose |
|---|---|---|---|
| RemoveDeathSkillLoss | Skip Skills.OnDeath entirely. The vanilla world modifier is not enough on its own: the accumulator wipe and the 'skills lowered' message sit outside the reduction factor, so zeroing it still discards partial progress toward the next level in every skill. | true | server |
Gate 7
| Setting | What it does | Default | Whose |
|---|---|---|---|
| CheckSkillBaseline | On login, take the character's skill list as the baseline this server pays from. Nothing is compared and nobody is judged: a character that turns up higher than this world last saw it gained that elsewhere and is simply not paid for it, because XP only ever comes from a level-up watched from here. Off leaves the baseline to fill in from observed play alone, which also turns off MaxSkillLevelJump - without a complete list, a skill never used cannot be told from one never seen. This replaces WithholdUntrustedXp, UntrustedMessage and SkillDriftAllowance, which marked such a character untrusted and paid it nothing 'until they line up again'. They never could: the withholding stopped the baseline advancing, and the baseline was the only thing that could have cleared it. Those keys may still be sitting in your config file doing nothing and can be deleted. Keeping a character out of a world altogether is a door policy - that is Dyrr. | true | server |
| CreditExistingSkills | Pay a joining character for the skills it already has, so a character that turns up worth twenty levels arrives at twenty levels with the picks to spend. Off starts every character at Rist level 0 no matter what it is carrying, and only level-ups watched from here earn anything. Not an estimate: XP is the skill level reached, so a skill at N has already produced 1+2+...+N. Summing that over every skill is exactly what the character would hold if all of it had happened here - which also makes it safe to re-run on every login, since a character that earned everything here is owed nothing and a skill lost to death cannot take levels away. On by default because the level is meant to sit beside the skills; without this it records which server you were standing on instead. If you would rather a well-travelled character could not join at all, that is a door policy rather than a payment one - see Dyrr. | true | server |
| MaxSkillUpsPerMinute | Server-side ceiling on accepted skill-up reports per player. A backstop only: skills live on the client, so reports are self-reported and this caps the damage rather than verifying anything. | 30 | server |
| MaxSkillLevelJump | How far above the highest level this server has watched a skill reach a single skill-up report may claim. One, because that is what the game does: skills level one at a time and fire one callback each, so a report of 87 from a server that last saw 12 did not come from playing. Raise it only if you run a mod that grants skill levels in bulk, which would otherwise trip this on every grant. Needs CheckSkillBaseline on, since without a login baseline an unseen skill cannot be told from an unused one and every first report would look forged. | 1 | server |
| MaxXpPerMinute | Ceiling on XP paid per player per minute of connected time. Zero or less turns it off. This is the only cap that does not depend on believing the client: however convincing a report is, time connected is a quantity the server measures for itself. 600 is far above honest play - it is thirty level-ups a minute, the report limit, on a skill at level 20 - and is meant to bound a flood rather than to shape progression. Use LevelBaseXp for that. | 600 | server |
| XpBurst | How much unspent earning allowance may bank, in XP. Three minutes' worth by default, and the allowance starts full so joining is never a wait. Without a bank the cap would be a per-minute tripwire that an honest burst of level-ups trips - clearing a crypt levels four skills at once - and the player would silently stop earning mid-fight. | 1800 | server |
| CappedMessage | Shown once per session, centre-screen, when the earning cap withholds XP. A cap that simply stops paying is invisible, so it says so once: invisible, and an honest player who hits one deserves to know why. | You are earning faster than this world will pay for. Rists will resume shortly. | server |
General 3
| Setting | What it does | Default | Whose |
|---|---|---|---|
| Enabled | Off leaves levels and cards recorded but stops granting or applying them. | true | server |
| Verbose | Log every XP grant, every rejected report and every runestone applied. Also dumps what the game's own UI is made of where this mod clones it - the compendium tab's layers and button colours, and the bar's fill colour and length. Both were written while chasing a cloned widget that drew the wrong thing, and they are the fastest way back to an answer if one ever does again. | false | server |
| ShowInfoTab | Add a fifth tab to the compendium bar, beside the raven and the trophy, that opens your rists. Cloned from a tab already there, so it carries the game's own frame, hover and click sound. | true | server |
Levelling 6
| Setting | What it does | Default | Whose |
|---|---|---|---|
| XpPerSkillLevel | XP granted per skill level-up, multiplied by the skill level reached. Weighting by level reached is deliberate: a flat rate would stall late progression exactly when the deep card ranks matter, and would make grinding a fresh cheap skill from zero the fastest way to farm cards. | 1 | server |
| LevelBaseXp | Cumulative XP needed for character level 1. Later levels scale by LevelExponent. Together with LevelExponent this is the whole pacing of the mod. The pair was 60 and 1.5 until it was played, and that asked for sixteen skill level-ups per rist by character level 20 - the reward simply stopped arriving. 40 and 1.4 roughly halves that at every level. | 40 | server |
| LevelExponent | Cumulative XP for level N is LevelBaseXp * N^LevelExponent. Above 1 means each level costs more than the last. Vanilla's own skill curve is already front-loaded, so this counteracts a flood of early cards. This is the shape rather than the scale: lowering it helps the late game far more than the early one, which is where the old 1.5 hurt. It is also what keeps the catalogue scarce - it holds one pick per card per rank, 135 with 27 cards at MaxRank 5, and a curve flat enough to hand out all of them turns a free choice into an order of purchase. Every card added makes the catalogue deeper against the same curve. | 1.4 | server |
| SkillWeights | What each skill is worth toward the character level, as Skill=multiplier pairs. A skill not named here is worth DefaultSkillWeight. The principle is risk: full price for a skill raised by something that can kill you, a fraction for one raised by repetition that cannot. This is not a guess at what felt wrong - the live ledger said it. A character at level 12 held 1346 xp of which WoodCutting alone was 666, Run, Jump and Crafting another 361, and everything earned in a fight came to 293. The level was mostly a record of trees felled in the Meadows. Under this table that same character is level 6 and over half of it came from fighting. Raising LevelBaseXp or LevelExponent cannot do this. Both scale the curve uniformly, so the ratio survives and the late game pays for it - which is what happened at 60 and 1.5 and had to be walked back. Names are the Skills.SkillType names and are case-insensitive; a raw type number also works, for a skill this game version has no name for. Negative weights are clamped to zero. Changing this affects new xp only until you also bump WeightGeneration. | "Swords=1, Knives=1, Clubs=1, Polearms=1, Spears=1, Axes=1, Bows=1, " + "Crossbows=1, Unarmed=1, Blocking=1, ElementalMagic=1, BloodMagic=1, " + "Dodge=0.5, Sneak=0.5, Swim=0.5, " + "WoodCutting=0.25, Pickaxes=0.25, Crafting=0.25, Farming=0.25, " + "Cooking=0.25, Fishing=0.25, Run=0.25, Jump=0.25, Ride=0.25" | server |
| DefaultSkillWeight | What a skill not named in SkillWeights is worth. One, so that a skill added by a game update or another mod is paid normally rather than silently going unpaid - an unnamed skill is far more likely to be an oversight than a deliberate zero. | 1 | server |
| WeightGeneration | Bump this - to any different text - to recompute every player's xp from the skill levels this server has watched them reach, under the weights standing now. Each character is recomputed once per value, on its next login, and the value it was last done at is written into the ledger line. This is the only thing that may move xp *downward*, and it is why it is a stamp rather than a switch. The routine per-login credit is deliberately one-way: it must never take levels away, or a skill lost to a death penalty would cost a card. A recompute has to be able to, so it is made a one-shot with a record of having run rather than something that fires every login. Cards already taken are kept. Someone recomputed from level 12 to level 6 keeps all twelve picks and earns no new ones until they pass twelve again, which is the honest reading - the picks were spent, and handing them back would be a free rebuild of the whole character rather than a re-pricing. | 1 | server |
Plate 2
| Setting | What it does | Default | Whose |
|---|---|---|---|
| ShowPlate | Write a Rist line above other players' heads: level, total XP, and days since they last died. Off also stops this character publishing its own three numbers, so nobody else can read them either. The numbers travel on the character's own network object, which means a player without Rist is simply shown their plain name. Days alive counts from the day this character first logged in with the plate on, not from the day it was created - the game keeps no birthday, so every existing character starts at 0 and grows from there. | true | server |
| PlateFormat | How the line above a player's head is written. Tokens: {lvl} character level, {xp} total experience, {days} days since their last death, {name} the name the game would have shown. Drop a token to drop that field. \n starts a new line. The plate is a TextMeshPro label, so it takes rich text: <color=#RRGGBB>, <size=65%>, <b> and the rest all work. Gold is the level, the bar's verdigris is the XP, and the days are red because that is the field that resets. For one line rather than two, put {name} first and delete the \n. | "<size=65%>(LVL <color=#E8C86E>{lvl}</color>)" + "[<color=#4FB3A5>{xp} XP</color>]" + "(<color=#C86464>{days} DAYS ALIVE</color>)</size>\\n{name}" | server |
Discussion
Nothing said yet.
Sign in or make an account to join in.