Violet

Familiar

On this page

Provides access to the familiar system including owned familiars, equipped presets, badges, and user state.

Familiar Object Structure

All familiar-returning functions provide objects with the following properties:

PropertyTypeDescription
snnumberUnique serial number (instance ID)
idnumberMob template ID (which monster)
character_idnumberOwner character ID
namestringCustom familiar name
levelnumberCurrent level
max_levelnumberMaximum level cap
expnumberCurrent experience
gradenumberRarity grade (see table below)
grade_expnumberGrade experience
add_padnumberBonus physical attack
add_pddnumberBonus physical defense
option1numberPotential line 1 ID (raw)
option2numberPotential line 2 ID (raw)
potentialstable<string>Array of resolved potential names (e.g. "Boss Damage +30%")
lockedbooleanWhether the familiar is locked

Familiar Grades

GradeName
0Common
1Rare
2Epic
3Unique
4Legendary

Functions

Collection

core.familiar.get_all() -> table<familiar>

Returns an array of all familiars the character owns.

lua
local familiars = core.familiar.get_all()
for _, f in ipairs(familiars) do
    core.log(string.format("%s (Lv.%d, Grade %d)", f.name, f.level, f.grade))
end

core.familiar.get_by_sn(serial_number: number) -> familiar | nil

Returns a specific familiar by its serial number, or nil if not found.

lua
local familiar = core.familiar.get_by_sn(12345)
if familiar then
    core.log("Found: " .. familiar.name)
end

core.familiar.get_count() -> number

Returns the total number of familiars owned.


Active State

core.familiar.get_summoned() -> familiar | nil

Returns the currently summoned familiar's full data, or nil if none is summoned.

lua
local summoned = core.familiar.get_summoned()
if summoned then
    core.log("Summoned: " .. summoned.name .. " (Lv." .. summoned.level .. ")")
end

core.familiar.get_equipped() -> table

Returns a table of up to 3 familiars in the active preset's equipped slots. Empty slots are nil.

lua
local equipped = core.familiar.get_equipped()
for i = 1, 3 do
    if equipped[i] then
        core.log("Slot " .. i .. ": " .. equipped[i].name)
    else
        core.log("Slot " .. i .. ": empty")
    end
end

core.familiar.get_badges() -> table

Returns an array of active badge entries (non-empty, non-0xFF slots). Each entry has:

PropertyTypeDescription
slotnumberBadge slot index (0-7)
badge_idnumberBadge group ID
lua
local badges = core.familiar.get_badges()
for _, b in ipairs(badges) do
    core.log("Badge slot " .. b.slot .. ": ID " .. b.badge_id)
end

User Info

core.familiar.get_user_info() -> table | nil

Returns familiar system state for the character, or nil if unavailable.

PropertyTypeDescription
fatiguenumberCurrent fatigue value
inventory_sizenumberFamiliar inventory capacity
summoned_snnumberSerial number of summoned familiar (0 if none)
versionnumberFamiliar system version
active_presetnumberActive familiar preset index (0-4)
active_badge_presetnumberActive badge preset index (0-4)
lua
local info = core.familiar.get_user_info()
if info then
    core.log("Preset: " .. info.active_preset)
    core.log("Fatigue: " .. info.fatigue)
end

Presets

core.familiar.get_preset_familiars(preset_index: number) -> table

Returns a table of 3 familiar serial numbers for the specified preset (0-4). SNs of 0 indicate empty slots.

lua
local sns = core.familiar.get_preset_familiars(0)
for i, sn in ipairs(sns) do
    if sn ~= 0 then
        local f = core.familiar.get_by_sn(sn)
        if f then core.log("Preset slot " .. i .. ": " .. f.name) end
    end
end

core.familiar.get_preset_badges(preset_index: number) -> table

Returns a table of 8 badge IDs for the specified badge preset (0-4).

lua
local badges = core.familiar.get_preset_badges(0)
for i, id in ipairs(badges) do
    if id ~= 0 and id ~= 255 then
        core.log("Badge " .. i .. ": " .. id)
    end
end

Mutations

core.familiar.apply_preset(preset_index: number, sn1: number, sn2: number, sn3: number) -> boolean

Writes the three familiar SNs into preset_index (0-4). Pass 0 for empty slots. Each non-zero SN is validated against the owned-familiar map before the packet is sent — stale SNs cause the server to disconnect, so this returns false and skips the send instead.

Does not change which preset is active — combine with set_active_preset if you want to switch.

lua
-- Save familiars 1234, 5678 into preset 0 with the third slot empty
core.familiar.apply_preset(0, 1234, 5678, 0)

core.familiar.set_active_preset(preset_index: number) -> boolean

Switches which familiar preset is currently active (0-4). Does not modify the preset's familiar layout — only changes which preset's familiars are active.

lua
core.familiar.set_active_preset(2)

Examples

List all familiars with potentials

lua
local familiars = core.familiar.get_all()
for _, f in ipairs(familiars) do
    local pot = ""
    if f.option1 ~= 0 then pot = pot .. " opt1=" .. f.option1 end
    if f.option2 ~= 0 then pot = pot .. " opt2=" .. f.option2 end
    core.log(string.format("[%s] %s Lv.%d Grade:%d%s",
        f.locked and "LOCK" or "    ",
        f.name, f.level, f.grade, pot))
end

Show equipped setup

lua
local info = core.familiar.get_user_info()
if not info then return end

core.log("=== Familiar Preset " .. info.active_preset .. " ===")
local equipped = core.familiar.get_equipped()
for i = 1, 3 do
    if equipped[i] then
        core.log(string.format("  Card %d: %s (Lv.%d)", i, equipped[i].name, equipped[i].level))
    end
end

core.log("=== Badges (Preset " .. info.active_badge_preset .. ") ===")
local badges = core.familiar.get_badges()
for _, b in ipairs(badges) do
    core.log(string.format("  Slot %d: Badge %d", b.slot, b.badge_id))
end