Skills
A player uses a skill from its skill window or a macro; a script tries a mobile at a skill with
skill.check, and the try may raise the skill. Twenty-one skills ship a script
(scripts/skills/): Hiding, Stealth, Snooping, Detecting Hidden, Anatomy, Animal Lore, Animal Taming, Evaluating
Intelligence, Forensic Evaluation, Tracking, Spirit Speak, Arms Lore, Peacemaking, Provocation, Discordance, Stealing, Meditation, Item Identification, Taste Identification, Begging and Poisoning; see Hiding and the other skill
scripts there. The rest of the game calls the same check as it is built.
Using a skill
Section titled “Using a skill”The client sends a text command (packet 0x12, kind 0x24) whose text starts with the number of
the skill, as 21 0 for Hiding.
- A dead character is refused with a message (cliloc 1019048), the staff included.
- A prisoner of the jail reads “You may not use skills in jail.” (message 30168); the staff is never refused.
- A character still waiting after its last skill reads “You must wait a few moments to use another skill.” (cliloc 500118), once a second at most.
- The script of the skill runs:
on_use(user)of the table named after the skill inscripts/skills/<skill>.lua, with the names ofdata/skills.toml(hiding,animal_lore). - A skill without a script answers “That skill cannot be used directly.” (500014), and asks no wait.
- The character then waits before another skill: the number
on_usereturns, in seconds from 0 to 3600; when it returns none, thedelayof the skill indata/skills.toml; one second when the file gives none either. Anon_usethat callswait()is still running when the wait is set: it asks thedelayof the skill, 10 seconds at least, and what it returns later is not read.
A skill script may define other functions that the server calls from elsewhere: on_snoop(user, owner, container) in snooping.lua runs when a player double clicks someone else’s container, instead of opening it.
animal_taming has delay = 30.0 in the toml, but its script always returns 1 second, so that value is never used.
The wait is of the character and one for all its skills, as in ModernUO. It is not saved: it does not outlive a restart.
-- scripts/skills/hiding.luahiding = {}
function hiding.on_use(user) if skill.check(user, "hiding", 0, 100) then mobile.set_hidden(user, true) endend[[skill]]id = "hiding"delay = 10.0The scripts are loaded at startup, as the item scripts are; the other kinds of text command (casting a spell, opening a door, an action) are read and not acted on yet.
The check
Section titled “The check”skill.check(who, skill, min, max) tries a mobile at a task: min is the points at which the
task can just be begun, max those at which it never fails.
| Points of the mobile | Result | Can it teach? |
|---|---|---|
Below min |
Fails | No |
At max or above |
Succeeds | No |
| In between | Succeeds with the chance (points - min) / (max - min) |
Yes |
So a task too hard or too easy teaches nothing, as in ModernUO.
The gain
Section titled “The gain”A try in between, passed or failed, may raise the skill of a player. NPCs never learn.
- Below 10.0 points a skill always learns.
- From 10.0 on, the chance is ModernUO’s: the mean of the room left under the total cap and under
the cap of the skill, then the mean of that and of how hard the task was (a pass counts half of
what was missing to the certainty, a failure a fifth), times the
gain_factorof the skill indata/skills.toml; never less than one in a hundred. - A skill up to 10.0 points gains from 0.1 to 0.4 points at a time, above it 0.1.
- A skill at its cap (100.0) does not rise, nor one whose lock is not up.
- The total of a player’s skills stops at
ultima.skills.total_cap(700.0 points). The nearer the total is to it, the more often a gain first lowers another skill whose lock is down by the same amount; at the cap, a skill rises only when one could be lowered. - A game master sets a skill by hand with
skill; the total cap does not apply to it.
The locks
Section titled “The locks”Each skill has a lock, up for every skill of a new character: the arrow beside it in the skill
window. The player moves it and the client tells the server (packet 0x3A), which keeps it with the
skill and saves it.
| Lock | The skill |
|---|---|
| Up | May rise when it is tried. |
| Down | Does not rise, and may be lowered to make room for another that rises when the total is at its cap. |
| Locked | Does not rise and is never lowered. |
A skill or a lock that does not exist is ignored.
ultima.skills.gain_enabled = false stops every gain: the checks still pass and fail.
The stats
Section titled “The stats”A successful check of a player can also raise strength, dexterity or intelligence, as ModernUO’s
classic rule, whether or not the skill itself rose (a failed check never does). The fields
str_gain, dex_gain and int_gain of the skill in data/skills.toml say how much the skill
favours each stat; a stat whose number is 0 is never tried by that skill.
- For each stat the skill favours and whose lock is up, a roll with the chance
gain / 33.3(a gain of 0.8 is 2.4%). - A stat that passes is tried once in
stat_gain_minutes(10): the wait starts when it is tried, even if nothing rises. It is kept in memory, not saved: after a restart a stat can be tried at once. - The more the three stats add up to near
stat_cap(225), the more often the player gives way: one point is taken from a stat locked down (above 10 points), the lower of the two when both can. Once the total is at the cap it always gives way. - If the total is then below
stat_cap, the stat is up and belowstat_max(100), it rises by one.
The maximum of its bar moves with it: strength the hit points, dexterity the stamina and intelligence the mana, and the player sees the whole status again. NPCs never gain stats.
Strength, dexterity and intelligence have a lock each, as the skills do, saved with the character:
the arrows beside them in the status window (0xBF subcommand 0x1A from the client, and 0x19 to
the client at login and each time a lock changes).
| Lock | The stat |
|---|---|
| Up | May rise when a skill is tried. |
| Down | Does not rise; gives a point away when another rises and the total is at the cap. |
| Locked | Does not rise and is never lowered. |
The wait of a stat is kept by character in memory, so logging out and in does not skip it; a restart
does. The three columns (str_lock, dex_lock, int_lock) are part of world.mobiles.
Trainers
Section titled “Trainers”A vendor, a healer or a stablemaster teaches the skills it has at 60.0 or more, as ModernUO’s trainers do. The skills are those of its mobile template, so a vendor teaches whichever skills rolled that high. Bankers do not teach: gold dropped on them is deposited.
- Ask. The context menu of the NPC has a Train entry for each skill it teaches and the player knows less of, from 8 tiles (12 for the stablemaster). Saying train within 4 tiles, alive, has the NPC list the skills it teaches, or say it has nothing to teach.
- Price. The NPC teaches up to a third of its own value, 42.0 at most and never above the player’s cap for the skill. Picking an entry makes it say the price: 1 gold for each tenth of a point, so 10 gold for a whole point (420 gold for 42.0), and that for less it teaches less. The quote lasts until it is paid, another one is given, or the session ends.
- Pay. The player drops gold on the NPC, from 2 tiles. The skill rises at once by one tenth of a point for each gold piece, up to what was quoted; only the gold needed is taken, and the rest of the pile stays with the player. A drop without a quote from that NPC, or of anything but gold, goes back.
- Refused. The player already knows as much as the NPC would teach (thou knowest all I can teach) or more; the
skill is not locked up, or the total cap (
ultima.skills.total_cap) leaves no room even after lowering the skills locked down, which give way in the order of the skills; the player is dead. A gold drop that can no longer teach gets the same answer, and the quote is dropped.
A script gives an NPC these lessons with the trainer module and common/training.lua; shopkeeper.lua, healer.lua and stablemaster.lua already do. trainer.skills(npc, player) lists the skills, trainer.quote(npc, player, skill) quotes a
price and trainer.pay(npc, giver, item) takes the gold, which is what an on_drag_drop answers.
Guildmasters
Section titled “Guildmasters”The twelve guildmasters of ModernUO (bard, blacksmith, fisher, healer, mage, merchant, miner, ranger, tailor, thief, tinker and
warrior) are mobile templates, a man (m_<trade>_guildmaster) and a woman (f_<trade>_guildmaster) for each, and an npc
list of the trade (<trade>guildmaster) that picks one. They are made by moongate-convert modernuo-guildmasters from
ModernUO’s classes: the title (the blacksmith guildmaster or guildmistress), the skills of the trade, the main ones
between 80 and 100, and the guild, and what they wear and carry for the trade: the blacksmith an apron or a ringmail chest, a bascinet and a
hammer, the mage and the healer a robe (in a blue or yellow hue) and the mage a staff. The kryss or dagger of the thief has no item
template yet. They are vendors like the others, so they teach what they know (Trainers); only the
blacksmith’s sells, as in ModernUO. The ModernUO spawns place them in the towns.
A guildmaster takes members for the guild of its trade. A player says the guildmaster’s name and join or member within 2 tiles to hear the price, 500 gold (the guildmaster speaks to that player only, over its head), and drops exactly that gold on it to join. A player belongs to one guild at most (the guild is a saved prop of the character) and is told when it is a member already or of another guild. The thieves’ guild asks for no kills and Stealing 60.0 (the thieves’ guildmaster of the towns of UOX3 is a guildmaster too, now). Saying the name and resign or quit leaves the guild, no sooner than a week after joining. The miner’s guildmaster names no guild in ModernUO, so it only teaches. A membership has no effect yet: nothing reads it. The age and the playing time ModernUO asks of a new member are not kept.
The template field npc_guild (blacksmiths, thieves…) makes an NPC a guildmaster, and the npcguild Lua module
(of, member, quote, is_join_payment, join, resign) with common/guild.lua gives its script the words and the gold.
See also
Section titled “See also”hiding.luabandage.lua: Healing, with the bandages- Animal Taming: the skill that makes a wild creature the player’s own
- The lore skills: Anatomy, Evaluating Intelligence, Forensic Evaluation and Detecting Hidden
tracking.lua: Tracking, with the quest arrowspirit_speak.lua: Spirit Speak, which makes the living understand the deadarms_lore.lua: Arms Lore, which reads a weapon or a piece of armorpeacemaking.lua: Peacemaking, which calms the creatures aroundprovocation.lua: Provocation, which sets two creatures against each otherdiscordance.lua: Discordance, which lowers the stats of a creaturestealing.lua: Stealing, which takes an item from a container or a creatureitem_identification.lua: Item Identification, which shows what an item istaste_identification.lua: Taste Identification, which finds the poison of foodmeditation.lua: Meditation, which halves the wait of mana while its trance lastsbegging.lua: Begging, which grovels a coin or two out of a human NPC- Camping: the kindling that lights a campfire, among the shipped item scripts
- Herding: the crook that walks a wild animal where the shepherd points
poisoning.lua: Poisoning, which rides a poison onto a blade or a piece of foodremove_trap.lua: Remove Trap, which renders the trap of a chest harmless- Server configuration:
[ultima.skills] - Roadmap: 1.2
Made with ❤️ by Tom
