Skip to content

jengine-skills

An isekai-style skill system - skills learned by use, levelled, evolved and fused, chanted spells, unique skills - as data tables; the rules of Reborn in Lumeria.

KindProject package: linked into the builds of the projects that list it
Sourcepackages/jengine-skills
Version0.1.0
Entry pointjengine_skills::SkillsPackage

List it in the top-level "packages" array of project.jengine:

{
"packages": [
{ "name": "jengine-skills", "source": { "type": "path", "path": "../../packages/jengine-skills" } }
]
}

Then rebuild the editor viewport for the project (jengine viewport-build projects/<name>, or the editor’s Rebuild viewport banner). Native and web builds link it on their own.

From packages/jengine-skills/README.md.

The skill and spell system of an isekai story - Reincarnated as a Slime, So I’m a Spider, So What?, Mushoku Tensei - as plain, unit-tested Rust with the content as data. Skills are learned by doing (swinging a sword trains [Swordsmanship], being hit trains [Pain Resistance]), rise from Lv1 to Lv10, evolve at the top (Fire Magic becomes Flame Magic), and two at the right levels can be integrated into a third when the player says YES to the system voice. A goddess grants each character one Unique Skill; titles come from deeds; spells are chanted, and chant skills cut the incantation short until it is cast without a word; monsters are weak or resistant to elements.

Written for Reborn in Lumeria (projects/lumeria), whose server room calls it. Any RPG here can use it: nothing in it knows about a room, a scene or a network, and the whole content is one JSON file a game can replace. A single-player game would call it from its own Rust package; an online one from its room, as Lumeria does.

use jengine_skills::{Character, SkillBook};
let book = SkillBook::isekai(); // content/isekai.json, checked
let mut hero = Character::new(&book, "Ada");
hero.reincarnate(&book, roll); // the goddess's gift - once, ever
let said = hero.use_action(&book, "melee_hit", 1.0); // report what happened...
for line in &said {
show(line.voice(), line.chime()); // ...show what the system voice says
}
// "《Proficiency has reached the required value. Skill [Swordsmanship Lv1] acquired.》"
TypeIs
SkillBookthe content: skills, spells, actions, fusions, uniques, titles, growth, chant rules. from_json validates every reference (a spell’s school, an evolution, a fusion’s result) and says what is wrong
Characterone character’s state, Serialize / Deserialize whole - a saved game, a player’s server state. New fields default, so an older save reads
Announcementwhat changed: Acquired, SkillLevel, SpellLearned, Evolved, FusionOffered, Fused, Unique, Title, Level, Devoured, Advice. voice() is the genre’s 《...》 line, chime() a category for a sound
CastPlanhow a spell would be cast now: cast time after chant skills, MP, the words said aloud (style: full, shortened, named, silent)
Statuseverything a status window shows, in one serializable value

The calls a game makes:

CallWhen
use_action(book, action, times)the player did something: melee_hit, hit_taken, burned, sprint (a second of it), appraise, gather, cast, cast:<element>, chant_full / chant_shortened / chant_named (a chant finished). The book’s actions map each to the skills it trains
plan_cast(book, spell)before chanting: refused with NotLearned / NoMana; a primer spell (each element’s first) may be cast without its school, clumsily - a full chant and a 35% longer cast - which is how the school is first learned
spell_hit / melee_hit / soak / interrupt_chancedamage out (weakness x1.75, resistance x0.5, criticals) and in (Pain Resistance, Fire Resistance), and the chance a blow breaks a chant
gain_xp, record_kill(family), record_deed(name)experience and levels (stats grow, health restored), and what earns titles
accept_fusion / decline_fusionthe answer to a FusionOffered. Offered once; a NO keeps it on offer; a second YES is refused
reincarnate(book, roll)the unique skill, by weight from the book’s table - and nothing at all for a character that already has one
devour(book, monster, skills, roll)[Predator]: take a skill a defeated monster has
insight(book)how much [Appraisal] shows: vitals from Lv1, weaknesses from Lv3, skills from Lv6
status(book)the status window

Practice follows evolutions: once Fire Magic has become Flame Magic, casting fire trains Flame Magic - it does not teach Fire Magic all over again - and a fusion that needs Fire Magic Lv5 counts the evolved skill as maxed.

content/isekai.json is the shipped book: five elements of magic (fire, water, wind, earth, light), each a school with three spells by Lv5 and an evolved form with a fourth; four integrated skills (Blaze Storm, Magma Magic, Tempest Magic, Sacred Flame); Swordsmanship, Pain Resistance, Fire Resistance, Sprint, Appraisal, Mana Control, Gathering and the chant ladder Chant Shortening -> Chant Omission -> Chantless Casting; seven unique skills (Great Sage, Predator, Infinite Mana, Hero’s Blessing, Lucky Star, Appraisal at Lv3, Chantless Casting at birth); two skills only Predator can take; and ten titles. A skill’s numbers are its acquire_at (practice to own it), first_level and growth (proficiency per level), bonus and per_level (stats and multipliers it adds), unlocks (spells by level), evolves_to and chant. They are tuned so a first skill is acquired in a minute or two of fighting and a fusion is reachable in a session.

The rules need no engine: a game’s server or package depends on the crate (jengine-skills = { path = ".../packages/jengine-skills" }) and calls it. The package registers no components, systems or script commands - it exists as a package so a project may list it, and SkillsPackage does nothing when hosted. A client draws what its server (or its own Rust) tells it; Lumeria’s client never links it.

cargo test -p jengine-skills: proficiency thresholds (acquired at exactly the sixth swing, Lv2 eight swings later); Great Sage doubling practice; spells unlocked by level; evolution at Lv10 and practice following it; a fusion offered only when both skills reach their levels, asked once, NO kept on offer, applied once; chant time and words at every rung of the chant ladder and unskilled; MP refusals; damage against weaknesses and resistances; levels and stat growth; titles from kills and deeds; Predator; reincarnation granting exactly one unique, once; a broken book refused with its problems; and a character surviving a serialization round trip (and an old save reading). The scene tests that play it through a real client are Lumeria’s (projects/lumeria/server/games/world/tests/play.rs).