Skip to content

Fenia API

Kit Oliynyk edited this page Nov 2, 2026 · 1 revision

TL;DR: Fenia's API is the set of C++ wrappers in plug-ins/feniaroot. It is documented by the running game itself: call api() on any value, read the generated page, or grep the wrapper source. This page says where to look and lists the root members and the public helper library. Use when: you need the name, arguments or result of a field or method, want to discover what an object offers, or look for a helper before you write one. Source of truth: dreamland_code/plug-ins/feniaroot/*wrapper.cpp, root.cpp, tableswrapper.cpp, src/core/fenia/ (lists, containers, scheduler), dreamland_fenia_public/utils/ Verified: 2026-11-02 against dreamland_code 88da8302, dreamland_world 43880467, dreamland_fenia_public c28874b. Root member lists and the helper index were generated from those sources on that date.

Do not write an API call from memory. Names drift, and a wrong name fails only when the line runs. Look it up first.

Where the truth lives

Source What it has Notes
In game: eval ptc(<value>.api()) Every field and method of that value, with a one-line description Works on the root (.api()), characters, items, rooms, lists, strings, tables and structs. The text is mostly Russian.
In game: eval ptc(<value>.rtapi()) Fields that scripts have set on it at runtime, for example triggers Use it to see which triggers a prototype has.
https://dreamland.rocks/feniaapi.html The same data as a web page, plus the flag tables Rendered from a JSON dump the server writes when its Fenia plugin starts, unless the server runs in buildplot mode. It does not list triggers, see Fenia-Triggers.
The wrapper source NMI_GET, NMI_SET and NMI_INVOKE lines. Each is one field or method with its doc string. The final authority. The generated page can lag behind a new binding.
dreamland_world/fenia.examples Templates for triggers, with argument lists The same templates the editors open with fenia <trigger>.

In the wrapper source, NMI_GET is a readable field, NMI_SET a writable one, and NMI_INVOKE a method. Naming a method without () gives a harmless 0 instead of an error (see Fenia-Gotchas).

Wrapper types

Value How you get it Source
root a leading . plug-ins/feniaroot/root.cpp
character (ch, mob, vict) trigger arguments, .players, .get_char_world(...) characterwrapper.cpp
player ch.pc, .Player(name) (works for offline players) playerwrapper.cpp
item trigger arguments, .get_obj_index(v).create(), room.items objectwrapper.cpp
item prototype .get_obj_index(vnum) objindexwrapper.cpp
mob prototype .get_mob_index(vnum) mobindexwrapper.cpp
room .get_room_index(vnum), ch.in_room roomwrapper.cpp
area prototype .get_area_index("midgaard.are"), .Area(file) areaindexwrapper.cpp
affect .Affect() affectwrapper.cpp
skill, spell, skill command, affect handler .Skill(n), .Spell(n), .SkillCommand(n), .AffectHandler(n) skillwrapper.cpp, spellwrapper.cpp, skillcommandwrapper.cpp, affecthandlerwrapper.cpp
behavior .Behavior(name) behaviorwrapper.cpp
area quest .AreaQuest(vnum) areaquestwrapper.cpp
religion, clan, race, profession, hometown, liquid, wearloc, material, language, bonus the root constructors listed below structwrappers.cpp
multi-language message ._("text"), .mm(en, ru, ua) multimessagewrapper.cpp
list, array, map, string see Fenia-Language src/core/fenia/reglist.cpp, plug-ins/feniaroot/reglistext.cpp, regcontainerext.cpp, idcontainerext.cpp, feniastringext.cpp
scheduler .scheduler src/core/fenia/schedulerwrapper.cpp
spell and skill contexts this inside spell and command hooks plug-ins/feniaroot/feniaspellext.cpp, plug-ins/skills_impl/feniaskillaction.cpp

Constructors that take a name throw when the name does not exist, for example .Behavior, .Religion, .AreaQuest. Getting a prototype with .get_mob_index(v) gives null for an unknown vnum instead. The two groups are easy to confuse. See Fenia-Gotchas.

Tables

Flag and enum tables hang off .tables:

.tables.item_table.furniture                    // one value
.tables.affect_flags.names(ch.affected_by)      // mask to names
.tables.sector_table.name(room.sector_type)     // enum value to name
.tables.res_flags.value("wood")                 // name to value
.tables.item_table.api()                        // print the whole table
.tables.api()                                   // print the list of tables

Members of a table: name(v) and names(mask), value(x) and values(x), message(v[, case[, lang]]), find("partial") for a lenient lookup, tabname, api(). Reading a flag that does not exist throws no such flag defined in bits.conf, and assigning to a table throws. The tables themselves are defined in dreamland_code/src/bits.conf and other .conf files.

Root members

Generated from root.cpp. Constructors start with a capital letter.

Methods and constructors:

Affect, AffectHandler, Area, AreaQuest, Array, AutoQuest, Behavior, Bonus, Clan,
CraftProfession, FeniaCommand, Hometown, Language, Liquid, List, Map, Material, Player,
Profession, Race, Religion, Skill, SkillCommand, SkillGroup, Spell, Wearloc, WordEffect,
_, abs, accountChars, add, api, apply, arg_is, arg_is_gold, arg_is_silver,
arg_is_strict, armorReductionAt, bestWeaponClass, chance, chanceOneOf, clearGuts,
codesource, config, configReload, craftRollArmor, craftRollWeapon, create_money, date,
declineUa, dice, discord, discord_clan, discord_wiznet, div, eval, findPlayer,
find_profession, finger, fmt, fmtLang, gecho, generateWeapon, getCurrentTime,
get_area_index, get_char_world, get_mob_index, get_obj_index, get_obj_world_unique,
get_random_room, get_random_room_vanish, get_room_index, help, imbueMagic, infonet,
infonetML, interpolate, isset_bit, itemAutoCost, itemCombatPoints, itemCost, itemOneM,
itemPoints, itemProcPoints, itemScore, itemWeight, itemWindowCurve, loadConfig,
logNotice, makeShort, max, min, mm, mult, number_percent, number_range, obj_by_id,
object, object2, power, print, questScroll, randomLiquid, randomWeaponTier,
randomizeArmor, randomizeMagic, randomizeNamedArmor, randomizeWeapon, repr, saveConfig,
savesChanceAt, savesModel, set_bit, set_bit_number, skills, spells, sqrt, sub, sync,
telegram, toHitModel, unset_bit, urange, weaponBaseRoll, weaponRefitBase, webcmd, wiznet

Fields:

areaIndexes, areaQuests, autoQuests, behaviors, buildplot, char_list, clanNames,
current_time, current_time_millis, day, day_of_epoch, feniadbStats, hometowns, hour,
materials, merchant_bank, mob_index_list, month, nanny, obj_index_list, object_list,
options, pcraces, playerNames, player_kills, players, professions, races, religions,
rooms, rooms_rain, scheduler, season, sky, sunlight, tables, tmp, world_time, year

Notes on a few of them:

  • Random and math: .chance(x) is true with probability x percent. .chanceOneOf(n) is true once in n. .number_percent() is 1 to 100. .number_range(a, b), .dice(n, sides), .max, .min, .abs, .urange(lo, x, hi) (clamp), .interpolate(x, x1, x2, y1, y2), .sqrt. For luck-aware rolls use .tmp.chance(base, ch).
  • Rational arithmetic: .add, .sub, .mult, .div, .power take numbers or numeric strings and return exact rationals as strings. Use them where you need fractions. + with a rational string truncates.
  • Bits: .set_bit(mask, bit), .unset_bit(mask, bit), .isset_bit(mask, bit), .set_bit_number(mask, n).
  • Time: .hour, .day, .month, .year, .season, .sunlight (0 night, 1 dawn, 2 day, 3 dusk), .sky (0 clear, 1 cloudy, 2 rain, 3 storm), .current_time, .world_time.
  • Lookup: .get_mob_index, .get_obj_index, .get_room_index, .get_area_index, .get_char_world (see the warning below), .get_random_room, .players, .char_list, .object_list, .mob_index_list, .obj_index_list, .rooms.
  • Config: .config("fight/mob_tiers") gives read-only access to a JSON config by name. .configReload(name) re-reads a few of the fight configs. Numbers there are integers.
  • Output: .fmt(fmt, args...) formats like act. .fmtLang(lang, fmt, args...) renders in a fixed language (0 EN, 1 RU, 2 UA). .mm(en, ru, ua) builds a message from three explicit texts. ._("ru text") looks the text up in the translation catalog, and the result is a message object, not a string. .webcmd(ch, cmd, label) makes a clickable link in the web client.
  • Broadcast: .gecho, .infonet, .wiznet, .discord*, .telegram.
  • Scripts: .apply(fn, this, argList), .codesource(fn) (the id of the code source of a function), .eval.
  • Editor buffers: ch.edReg([n[, text]]) reads or sets the registers of the line editor, see OLC-Line-Editor.
  • Additional professions: .CraftProfession(name) wraps a craft profession. setLevel(ch, level), gainExp(ch, exp) and getExpToLevel(ch) set and test a character's mastery, and nameMlt is the plural name with cases.
  • Offline players: .Player(name) wraps a player even when offline. Its setters, setAttribute and eraseAttribute save the profile at once (saving moves the last-seen time to now (unverified)). Fenia fields on the online character are a different store.
  • .get_char_world(name) on the root is for the login flow. In scripts use ch.get_char_world(...), which matches English, Russian and Ukrainian names (unverified).

Public helper library

Scripts in dreamland_fenia_public/utils define 214 helper functions under .tmp.<namespace>. Call them as .tmp.<namespace>.<function>(...). Check this list before you write common logic inline, for example .tmp.currency.canAfford(ch, 50, "qp") instead of comparing questpoints by hand.

A namespace may also be extended by scripts in the private repository, so the full catalogue on a live server is larger. List it in game with cs list utils. Some public helpers call helpers that only the private scripts define, for example .tmp.chance calls .tmp.religion.hasMark. On a server built from the public repositories alone, such a call throws until you provide that helper (read from the source, not run on a bare server).

Namespace Count Covers Functions
.tmp.chance 1 Luck-aware chance roll and the religion-mark roll. (base_chance, ch)
.tmp.currency 10 Paying and gaining quest points, gold, silver, items and experience. canAfford(ch, amount, currency), adjustPrice(ch, servicer, amount), gainItem(ch, vnum, verbose), gainXP(ch, amount, verbose), gainQP(ch, amount, verbose), payQP(ch, amount, verbose), printMoney(amount, lang), printGoldSilver(gold, silver, gcase), gainMoney(ch, amount, verbose), pay(ch, amount, verbose)
.tmp.system 17 Sleep, extraction, number and string helpers, trilingual message picker, transliteration. inflect_name(name, gender, gcase), sleep(t), sleep_online(ch, t), trueExtract(obj_or_mob), toNumber(num), power(x, y), lmsg(lang, en, ru, ua), concatComma(msgs), concatCommaAnd(msgs), concatCommaAndL(msgs, lang), getOneKeyword(string, russian), objVisMsg(ch, obj, case), raffectDescr(af, msg), recolorDescr(descr, main_color, accents, accent_chance), translit(input), translit_reverse(input), ua_letters_to_ru(input)
.tmp.mob 84 Character and mob queries, mob casting checks, elemental effect appliers, service-mob helpers. valid(ch), hasOwnAffect(ch, name), awake(ch), canMove(ch), isActive(ch), canActAmbient(mob), boatType(ch), weight(ch), isBlind(ch), canGreet(ch, vict), canMakeSound(ch), isSilent(ch), canSpeak(ch), canFly(ch), isUndead(ch), isStrongTier(ch, maxTier), tierDuration(ch, duration), tierStackCap(ch), isObject(ch), isEthereal(ch), isBloodless(ch), isColdBlooded(ch), isBeastForm(form), isBeast(ch), hasLegs(ch), hasPaws(ch), hasHands(ch), hasFreeHand(ch), hasPart(ch, bit_or_name), partVnum(bit_or_name), isInternalPart(part), checkPartAffects(ch), wearCheck(ch, obj), canWear(ch, obj), hasObjWearloc(ch, wearloc), canFall(ch), getAttackDamage(ch), getWeapons(ch), getWeaponSkill(ch), hasWeaponType(ch, weapon_type), health(ch), masterHere(mob), getKillerHere(killer), canAutoCast(mob), canCastOn(mob, vict), canCastSupport(mob, vict), canCastOffensive(mob, vict), hasService(ch), isServicer(ch), isJeweler(ch), canRescue(ch, victim, verbose), canRescueMaster(ch), get_obj_behavior(mob, bhv), sameAlign(ch, vict), oppositeAlign(ch, vict), stampHeatSource(obj, src), burnByItem(ch, obj, apply_damage, attacker), effectFire(ch, fire_power, heat_items, apply_damage), effectFireBy(ch, attacker, fire_power, heat_items, apply_damage), chillJoin(ch, af), effectColdGear(ch, cold_power, apply_damage), effectCold(ch, cold_power, freeze_items, apply_damage), effectShock(ch, shock_power, affect_items, apply_damage), poisonRun(ch, poison_power, affect_items, apply_damage, kind), effectAcid(ch, acid_power, affect_items, apply_damage), effectPoison(ch, poison_power, affect_items, apply_damage), effectPoisonCloud(ch, poison_power, affect_items, apply_damage), sandRun(ch, sand_power, affect_items, apply_damage, kind), effectSand(ch, sand_power, affect_items, apply_damage), effectSandCloud(ch, sand_power, affect_items, apply_damage), effectScream(ch, scream_power, affect_items, apply_damage), shockDropWeapon(ch), serviceNameMM(service, gcase), findServicers(client, argument), canServe(mob, client), canRepair(mob, obj), getServices(mob), listServices(mob, client), locateService(mob, client, argument), estimateService(mob, client, service), canPerformService(mob, client, service), serviceProgress(client, service), hagglePrice(client, mob, old_price), doService(mob, client, service)
.tmp.movetype 2 Danger modifiers of movement types. dangerMod(danger), entryShift(danger)
.tmp.object 33 Item queries, destruction and wear checks, puddles, trap landings. special(obj), rarityTier(obj), repairPrice(obj), indestructible(obj), isElastic(obj), getMaterialConfig(material_name), materialHasFlag(obj, flag), valid(obj), hasWearloc(obj, name), canDrop(obj), canRemove(obj), movable(ch, obj), removableEquip(ch), isWeapon(obj), getWeaponClass(obj), hasBlade(obj), hasPole(obj), armorCoef(obj), getTrueAC(obj), calculateCost(obj, tier), savesDispel(dispel_level, affect_level, duration), castLevel(obj), make_puddle(liquid, amount, poisoned), create_puddle(liquid, room, amount, poisoned), create_rain_puddle(room), puddleTimer(amount), namePuddle(puddle, liq), spill_puddle(liquid, room, amount, poisoned, verbose), puddleLanding(room), trapTarget(room), trapLanding(room), stuckLanding(stuck, start), dimensions(obj)
.tmp.profiler 2 Start and stop a named timer. start(label), stop(label)
.tmp.room 27 Room queries, fire, flood and element effects on rooms. canBurn(room), heatSource(af), burn(room, level, duration, source), extinguish(room, level, ch), flood(room, level, duration, sector, source), makeLog(hardOnly), dropTree(room), getTreeStats(room), updateForest(room, level, stats), echo(room, msg), dropWhere(room), dropPick(room, variants), dropWhereRaw(room), hasPuddles(room), hasSnow(room), isIntroArea(room), savesDispel(affect, dispel_level, ch), get_obj_behavior(room, bhv), elementModKind(room, element, kind), elementMod(room, element), effectFire(room, source_ch, power), effectCold(room, source_ch, power), effectShock(room, source_ch, power), effectSand(room, source_ch, power), effectScream(room, source_ch, power), effectAcid(room, source_ch, power), effectPoison(room, source_ch, power)
.tmp.time 22 Durations, time printing, relative "ago" phrases, Kyiv calendar. days_to_seconds(duration), hours_to_seconds(duration), minutes_to_seconds(duration), print(time), unitL(count, lang, en, ru, ua), printL(time, lang), daysFromCivil(y, m, d), lastSunday(y, m), kyivOffset(t), kyivDay(t), agoUnitL(count, lang, en, ru, ua), weekdayOnL(dow, lang), agoL(then, lang), seconds(duration), minutes(duration), hours(duration), days(duration), weeks(duration), months(duration), years(duration), tierDays(tier), tier(tier)
.tmp.trap 5 Trap detection and triggering. work(ch, trap), detects(ch, train), matches(ch, trap, movedanger, train), capture(ch, trap), roomHazard(room)
.tmp.weight 10 Item and money weight. calculateWeight(obj), calculateWeightAs(obj, heft), effectWeight(obj), effectWeightScale(obj), effectCarry(ch), gold(amount), silver(amount), money(amount), canCarryMoney(ch, amount), canCarryItem(ch, obj)

.tmp.chanceMark(ch) is part of the chance file. The services helpers for service mobs are filed under .tmp.mob, and translit and inflect under .tmp.system.

Helpers that read a .Map() may be read-only on purpose. Do not store into the .tmp namespaces of the library from your own scripts, add your own namespace instead.

See also

Clone this wiki locally