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.
| Kind | Project package: linked into the builds of the projects that list it |
| Source | packages/jengine-skills |
| Version | 0.1.0 |
| Entry point | jengine_skills::SkillsPackage |
Using it
Section titled “Using it”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.
The shape
Section titled “The shape”use jengine_skills::{Character, SkillBook};
let book = SkillBook::isekai(); // content/isekai.json, checkedlet mut hero = Character::new(&book, "Ada");hero.reincarnate(&book, roll); // the goddess's gift - once, everlet 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.》"| Type | Is |
|---|---|
SkillBook | the 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 |
Character | one character’s state, Serialize / Deserialize whole - a saved game, a player’s server state. New fields default, so an older save reads |
Announcement | what changed: Acquired, SkillLevel, SpellLearned, Evolved, FusionOffered, Fused, Unique, Title, Level, Devoured, Advice. voice() is the genre’s 《...》 line, chime() a category for a sound |
CastPlan | how a spell would be cast now: cast time after chant skills, MP, the words said aloud (style: full, shortened, named, silent) |
Status | everything a status window shows, in one serializable value |
The calls a game makes:
| Call | When |
|---|---|
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_chance | damage 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_fusion | the 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.
The content
Section titled “The content”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.
Using it
Section titled “Using it”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).