<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.bconomy.net/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AItems_navbox</id>
	<title>Module:Items navbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.bconomy.net/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AItems_navbox"/>
	<link rel="alternate" type="text/html" href="https://wiki.bconomy.net/w/index.php?title=Module:Items_navbox&amp;action=history"/>
	<updated>2026-11-06T05:47:58Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://wiki.bconomy.net/w/index.php?title=Module:Items_navbox&amp;diff=7034&amp;oldid=prev</id>
		<title>Wewert at 14:20, 5 November 2026</title>
		<link rel="alternate" type="text/html" href="https://wiki.bconomy.net/w/index.php?title=Module:Items_navbox&amp;diff=7034&amp;oldid=prev"/>
		<updated>2026-11-05T14:20:21Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function has(values, wanted)&lt;br /&gt;
    for _, value in ipairs(values or {}) do&lt;br /&gt;
        if value == wanted then return true end&lt;br /&gt;
    end&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function currentGroup(entry)&lt;br /&gt;
    local presentation = entry.presentation or {}&lt;br /&gt;
    local boost = presentation.boostTier&lt;br /&gt;
    if boost then return &amp;#039;boosts&amp;#039;, boost.category end&lt;br /&gt;
    if entry.effect then&lt;br /&gt;
        if entry.effect.type == &amp;#039;actionBoost&amp;#039; then&lt;br /&gt;
            local actions = {fish=&amp;#039;Fish&amp;#039;, hunt=&amp;#039;Hunt&amp;#039;, mine=&amp;#039;Mine&amp;#039;, explore=&amp;#039;Explore&amp;#039;, work=&amp;#039;Work&amp;#039;}&lt;br /&gt;
            return &amp;#039;boosts&amp;#039;, actions[entry.effect.action] or &amp;#039;Other&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
        return &amp;#039;boosts&amp;#039;, &amp;#039;Rare loot&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    if entry.petAdventureBoostEffect then return &amp;#039;boosts&amp;#039;, &amp;#039;Pet&amp;#039; end&lt;br /&gt;
    if entry.farmPlotBoostEffect then return &amp;#039;boosts&amp;#039;, &amp;#039;Farm&amp;#039; end&lt;br /&gt;
    if entry.augmentProperties then return &amp;#039;boosts&amp;#039;, &amp;#039;Tool&amp;#039; end&lt;br /&gt;
    if presentation.loot and presentation.loot[1] then return &amp;#039;boxes&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if entry.damage or entry.damageMultiplier then return &amp;#039;weapons&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if has(entry.attributes, &amp;#039;equippable&amp;#039;) then return &amp;#039;equipment&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if entry.growTime then return &amp;#039;crops&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if entry.petEnergy then return &amp;#039;food&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if entry.worthPerGainedFromBurn then return &amp;#039;pyre&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if has(entry.attributes, &amp;#039;relayItem&amp;#039;) then return &amp;#039;relay&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    if has(entry.lootSources, &amp;#039;rare&amp;#039;) then return &amp;#039;rare&amp;#039;, &amp;#039;&amp;#039; end&lt;br /&gt;
    for _, source in ipairs({&amp;#039;explore&amp;#039;, &amp;#039;fish&amp;#039;, &amp;#039;hunt&amp;#039;, &amp;#039;mine&amp;#039;}) do&lt;br /&gt;
        if has(entry.lootSources, source) then return &amp;#039;materials&amp;#039;, source end&lt;br /&gt;
    end&lt;br /&gt;
    if not entry.uncraftable then return &amp;#039;materials&amp;#039;, &amp;#039;crafted&amp;#039; end&lt;br /&gt;
    return &amp;#039;materials&amp;#039;, &amp;#039;other&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function worth(entry)&lt;br /&gt;
    local value = tonumber(entry.cost)&lt;br /&gt;
    -- Unknown final worth is placed after known values, without inventing zero.&lt;br /&gt;
    return value and value &amp;gt;= 0 and value or math.huge&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function less(a, b)&lt;br /&gt;
    if a.worth ~= b.worth then return a.worth &amp;lt; b.worth end&lt;br /&gt;
    local left, right = mw.ustring.lower(a.name), mw.ustring.lower(b.name)&lt;br /&gt;
    if left ~= right then return left &amp;lt; right end&lt;br /&gt;
    return a.article &amp;lt; b.article&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Values and current Item membership are supplied by the existing reference&lt;br /&gt;
-- poller. The registry selects canonical removed concepts from the frozen archive;&lt;br /&gt;
-- it intentionally does not infer identity from reused numeric Item slots.&lt;br /&gt;
function p.groups(reference, archive, registry)&lt;br /&gt;
    local grouped, seen = {}, {}&lt;br /&gt;
    local function add(group, subgroup, entry, article)&lt;br /&gt;
        local title = article or entry.article or entry.name&lt;br /&gt;
        if seen[title] then error(&amp;#039;Duplicate Item navigation article: &amp;#039; .. title) end&lt;br /&gt;
        seen[title] = true&lt;br /&gt;
        grouped[group] = grouped[group] or {}&lt;br /&gt;
        grouped[group][subgroup] = grouped[group][subgroup] or {}&lt;br /&gt;
        table.insert(grouped[group][subgroup], {&lt;br /&gt;
            article=title, name=article or entry.name, worth=worth(entry)&lt;br /&gt;
        })&lt;br /&gt;
    end&lt;br /&gt;
    for _, entry in pairs(reference.items) do&lt;br /&gt;
        if not entry.retired then&lt;br /&gt;
            local group, subgroup = currentGroup(entry)&lt;br /&gt;
            add(group, subgroup, entry)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for key, article in pairs(registry.removedItems) do&lt;br /&gt;
        local entry = archive.items[key]&lt;br /&gt;
        if not entry or entry.status ~= &amp;#039;removed&amp;#039; then&lt;br /&gt;
            error(&amp;#039;Missing removed Item navigation record: &amp;#039; .. key)&lt;br /&gt;
        end&lt;br /&gt;
        add(&amp;#039;removed&amp;#039;, registry.removedTypes[entry.type] or &amp;#039;utilities&amp;#039;, entry, article)&lt;br /&gt;
    end&lt;br /&gt;
    for _, subgroups in pairs(grouped) do&lt;br /&gt;
        for _, entries in pairs(subgroups) do table.sort(entries, less) end&lt;br /&gt;
    end&lt;br /&gt;
    return grouped&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function links(cell, entries)&lt;br /&gt;
    local list = cell:tag(&amp;#039;ul&amp;#039;):addClass(&amp;#039;bc-release-links&amp;#039;)&lt;br /&gt;
    for _, entry in ipairs(entries) do&lt;br /&gt;
        list:tag(&amp;#039;li&amp;#039;):wikitext(&amp;#039;[[&amp;#039; .. mw.text.nowiki(entry.article) .. &amp;#039;|&amp;#039; .. mw.text.nowiki(entry.name) .. &amp;#039;]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.render()&lt;br /&gt;
    local reference = mw.loadJsonData(&amp;#039;GameData:Reference.json&amp;#039;)&lt;br /&gt;
    local archive = mw.loadJsonData(&amp;#039;GameData:Historical items.json&amp;#039;)&lt;br /&gt;
    local registry = mw.loadJsonData(&amp;#039;GameData:Item navigation.json&amp;#039;)&lt;br /&gt;
    local groups = p.groups(reference, archive, registry)&lt;br /&gt;
    local root = mw.html.create(&amp;#039;table&amp;#039;):addClass(&amp;#039;bc-navbox-table bc-item-nav-table&amp;#039;)&lt;br /&gt;
    for _, definition in ipairs(registry.groups) do&lt;br /&gt;
        local group = groups[definition.key]&lt;br /&gt;
        if group then&lt;br /&gt;
            local row = root:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
            row:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;scope&amp;#039;, &amp;#039;row&amp;#039;):addClass(&amp;#039;bc-item-nav-group&amp;#039;):wikitext(mw.text.nowiki(definition.label))&lt;br /&gt;
            local body = row:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
            if definition.subgroups then&lt;br /&gt;
                body:addClass(&amp;#039;bc-item-nav-body&amp;#039;)&lt;br /&gt;
                local nested = body:tag(&amp;#039;table&amp;#039;):addClass(&amp;#039;bc-navbox-months bc-item-nav-subgroups&amp;#039;)&lt;br /&gt;
                local emitted = {}&lt;br /&gt;
                local function subgroup(key, label)&lt;br /&gt;
                    if not group[key] or #group[key] == 0 then return end&lt;br /&gt;
                    emitted[key] = true&lt;br /&gt;
                    local subrow = nested:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
                    subrow:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;scope&amp;#039;, &amp;#039;row&amp;#039;):wikitext(mw.text.nowiki(label))&lt;br /&gt;
                    links(subrow:tag(&amp;#039;td&amp;#039;), group[key])&lt;br /&gt;
                end&lt;br /&gt;
                for _, sub in ipairs(definition.subgroups) do subgroup(sub.key, sub.label) end&lt;br /&gt;
                -- New feed classifications remain visible pending editorial labels.&lt;br /&gt;
                local unknown = {}&lt;br /&gt;
                for key in pairs(group) do if not emitted[key] then table.insert(unknown, key) end end&lt;br /&gt;
                table.sort(unknown)&lt;br /&gt;
                for _, key in ipairs(unknown) do subgroup(key, key == &amp;#039;&amp;#039; and &amp;#039;Other&amp;#039; or key) end&lt;br /&gt;
            else&lt;br /&gt;
                links(body, group[&amp;#039;&amp;#039;] or {})&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return tostring(root)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wewert</name></author>
	</entry>
</feed>