I am trying to have modded items in the chests of lost cites mod, and there is this problem I am facing, in which a mod called Apocalypse Now automatically injects its mod items into the chests without having a need of datapack, which suggests its being done internally within the mod. What I have found is that it is overwriting loot tables entirely and by that, lootjs/kubejs or the datapacks of the another mod does not inject their itmes.
That another mod is Timeless and Classics Zero, and I made the datapacks and the json file (later) for this mods by taking help of multiple chatbots, since I lack knowledge on making datapacks or json file for the lootjs/kubejs to overwrite or just add your loot to the loot tables without overwriting it. I will have the contents of those files written down below, by which you can see if there are errors or not in those 3 files.
- Datapack for the timeless and classics zero mod:
a. add_tacz_apartment.json
"type": "forge:add_items", "conditions": [ { "condition": "forge:loot_table_id", "loot_table_id": "minecraft:chests/apartament" } ], "items": [ { "item": "tacz:modern_kinetic_gun", "weight": 100, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:glock_17\\\",GunCurrentAmmoCount:7}" }, { "function": "minecraft:set_name", "name": { "text": "Glock 17", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 6, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:uzi\\\",GunCurrentAmmoCount:25}" }, { "function": "minecraft:set_name", "name": { "text": "Uzi", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 6, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:db_short\\\",GunCurrentAmmoCount:2}" }, { "function": "minecraft:set_name", "name": { "text": "Sawed-off", "italic": false } } ] }, { "item": "tacz:sight_uh1", "weight": 8 }, { "item": "tacz:sight_552", "weight": 8 }, { "item": "tacz:muzzle_silencer_phantom_s1", "weight": 4 }, { "item": "tacz:muzzle_compensator_trident", "weight": 4 }, { "item": "tacz:ammo_9mm", "weight": 12 }, { "item": "tacz:ammo_12g", "weight": 10 }, { "item": "tacz:ammo_45acp", "weight": 4 } ] } b. add_tacz_lostcitychest.json
"type": "forge:add_items", "conditions": [ { "condition": "forge:loot_table_id", "loot_table_id": "lostcities:chests/lostcitychest" } ], "items": [ { "item": "tacz:modern_kinetic_gun", "weight": 4, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:ak47\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "AK-47 (abandoned)", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 6, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:db_short\\\",GunCurrentAmmoCount:2}" }, { "function": "minecraft:set_name", "name": { "text": "Sawed-off", "italic": false } } ] }, { "item": "tacz:sight_rmr_dot", "weight": 4 }, { "item": "tacz:light_extended_mag_3", "weight": 1 }, { "item": "tacz:ammo_9mm", "weight": 12 }, { "item": "tacz:ammo_45acp", "weight": 4 }, { "item": "tacz:ammo_12g", "weight": 8 } ] } c. add_tacz_raildungeon.json
"type": "forge:add_items", "conditions": [ { "condition": "forge:loot_table_id", "loot_table_id": "lostcities:chests/raildungeonchest" } ], "items": [ { "item": "tacz:modern_kinetic_gun", "weight": 6, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:ak47\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "AK-47 (abandoned)", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 3, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:sks_tactical\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "SKS (rifle)", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 3, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:type_81\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "Type 81", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 1, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:aa12\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "AA-12 (very rare)", "italic": false } } ] }, { "item": "tacz:modern_kinetic_gun", "weight": 1, "functions": [ { "function": "minecraft:set_nbt", "tag": "{GunId:\\\"tacz:m320\\\",GunCurrentAmmoCount:0}" }, { "function": "minecraft:set_name", "name": { "text": "M320 (very rare)", "italic": false } } ] }, { "item": "tacz:scope_acog_ta31", "weight": 4 }, { "item": "tacz:scope_vudu", "weight": 3 }, { "item": "tacz:scope_mk5hd", "weight": 1 }, { "item": "tacz:muzzle_brake_cyclone_d2", "weight": 4 }, { "item": "tacz:sight_deltapoint_pistol", "weight": 4 }, { "item": "tacz:ammo_556x45", "weight": 10 }, { "item": "tacz:ammo_762x39", "weight": 10 }, { "item": "tacz:ammo_30_06", "weight": 4 }, { "item": "tacz:ammo_45_70", "weight": 2 } ] } - loot_integration.json (file for kubejs/lootjs)
// Defensive LootJS injector — tries multiple API names and catches all errors. // Replace your existing file with this. It will not throw TypeError on missing methods. (function() { function log() { try { console.log("[KubeJS-LOOTFIX]", Array.prototype.join.call(arguments, " ")); } catch (e) {} } // Items to inject (same lists you used) const taczItemsApartment = [ { item: "tacz:sight_uh1", weight: 8 }, { item: "tacz:sight_552", weight: 8 }, { item: "tacz:muzzle_silencer_phantom_s1", weight: 4 }, { item: "tacz:muzzle_compensator_trident", weight: 4 }, { item: "tacz:ammo", weight: 12, nbt: '{AmmoId:"tacz:9mm"}' }, { item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:12g"}' }, { item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:45acp"}' }, { item: "tacz:modern_kinetic_gun", weight: 8, nbt: '{GunId:"tacz:glock_17",GunCurrentAmmoCount:7}' }, { item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:uzi",GunCurrentAmmoCount:25}' }, { item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:db_short",GunCurrentAmmoCount:2}' } ]; const taczItemsRailDungeon = [ { item: "tacz:scope_acog_ta31", weight: 4 }, { item: "tacz:scope_vudu", weight: 3 }, { item: "tacz:scope_mk5hd", weight: 1 }, { item: "tacz:muzzle_brake_cyclone_d2", weight: 4 }, { item: "tacz:sight_deltapoint_pistol", weight: 4 }, { item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:556x45"}' }, { item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:762x39"}' }, { item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:30_06"}' }, { item: "tacz:ammo", weight: 2, nbt: '{AmmoId:"tacz:45_70"}' }, { item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:ak47",GunCurrentAmmoCount:0}' }, { item: "tacz:modern_kinetic_gun", weight: 3, nbt: '{GunId:"tacz:sks_tactical",GunCurrentAmmoCount:0}' }, { item: "tacz:modern_kinetic_gun", weight: 3, nbt: '{GunId:"tacz:type_81",GunCurrentAmmoCount:0}' }, { item: "tacz:modern_kinetic_gun", weight: 1, nbt: '{GunId:"tacz:aa12",GunCurrentAmmoCount:0}' }, { item: "tacz:modern_kinetic_gun", weight: 1, nbt: '{GunId:"tacz:m320",GunCurrentAmmoCount:0}' } ]; const taczItemsLostCity = [ { item: "tacz:sight_rmr_dot", weight: 4 }, { item: "tacz:light_extended_mag_3", weight: 1 }, { item: "tacz:ammo", weight: 12, nbt: '{AmmoId:"tacz:9mm"}' }, { item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:45acp"}' }, { item: "tacz:ammo", weight: 8, nbt: '{AmmoId:"tacz:12g"}' }, { item: "tacz:modern_kinetic_gun", weight: 4, nbt: '{GunId:"tacz:ak47",GunCurrentAmmoCount:0}' }, { item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:db_short",GunCurrentAmmoCount:2}' } ]; // low-level helper: safely try to call a method on event function tryCall(event, methodName, argsArray) { try { const fn = event[methodName]; if (typeof fn === "function") { return fn.apply(event, argsArray); } // If fn is not a JS function, still attempt to call (some Java proxies allow direct call) if (fn !== undefined) { try { return fn(argsArray); } catch (e) { /* ignore */ } } } catch (e) { // swallow errors so script doesn't crash } return null; } // helper: add items using a table/context object function populateTableLikeObject(tblOrCtx, items) { try { // preferred API: tblOrCtx.addPool(pool => { pool.addItem(...).withNBT(...) }) if (typeof tblOrCtx.addPool === "function") { tblOrCtx.addPool(function(pool) { // if pool.rolls exists, set single roll try { if (typeof pool.rolls === "function") pool.rolls([1,1]); } catch(e){} items.forEach(function(entry) { try { if (entry.nbt && typeof pool.addItem === "function") { // chain withNBT if available const e = pool.addItem(entry.item, entry.weight || 1); // some APIs return a wrapper with withNBT, others not - guard it try { if (typeof e.withNBT === "function") e.withNBT(entry.nbt); } catch(e){} } else if (typeof pool.addItem === "function") { pool.addItem(entry.item, entry.weight || 1); } else if (typeof pool.add === "function") { // older variant: pool.add({ item:..., weight:... }) pool.add({ item: entry.item, weight: entry.weight || 1, nbt: entry.nbt || null }); } } catch (errEntry) { // skip problematic entry } }); }); return true; } // fallback: if ctx/table has add or addItem methods if (typeof tblOrCtx.add === "function") { try { tblOrCtx.add(items); return true; } catch(e) {} } if (typeof tblOrCtx.addItem === "function") { items.forEach(function(entry) { try { const e = tblOrCtx.addItem(entry.item, entry.weight || 1); try { if (entry.nbt && typeof e.withNBT === "function") e.withNBT(entry.nbt); } catch(e){} } catch(e){} }); return true; } } catch (e) { // swallow } return false; } // Tries a bunch of method names in defensive order. Returns true on first success. function tryModifyTable(event, tableId, items) { // candidate API names to try, in order const candidates = [ "modifyLootTable", "modify_table", "modifyTable", "modify", "modify_loot_table" ]; for (let i = 0; i < candidates.length; i++) { const name = candidates[i]; try { // Attempt to call event[name](tableId, callback) const res = tryCall(event, name, [tableId, function(tblOrCtx) { const ok = populateTableLikeObject(tblOrCtx, items); if (!ok) { // As a fallback, try to call tblOrCtx.add(items) try { if (typeof tblOrCtx.add === "function") tblOrCtx.add(items); } catch(e) {} } }]); if (res !== null) { log("Used API:", name, "for table:", tableId); return true; } } catch (err) { // continue trying next candidate } } // Final fallback: maybe event has an 'add' that accepts an object like { id, items } try { if (typeof event.add === "function") { try { event.add({ id: tableId, items: items }); log("Used event.add fallback for", tableId); return true; } catch(e){} } } catch (e) {} // As last resort, log event keys for debugging try { const keys = Object.keys(event).join(", "); log("No supported modify API found for table", tableId, " — event keys:", keys); } catch (e) { log("No supported modify API found and couldn't list event keys."); } return false; } // Main entry: call inside LootJS.modifiers LootJS.modifiers(function(event) { try { let did1 = tryModifyTable(event, "minecraft:chests/apartament", taczItemsApartment); let did2 = tryModifyTable(event, "lostcities:chests/raildungeonchest", taczItemsRailDungeon); let did3 = tryModifyTable(event, "lostcities:chests/lostcitychest", taczItemsLostCity); log("Injection results — apartament:", !!did1, "raildungeon:", !!did2, "lostcity:", !!did3); } catch (e) { log("Unexpected error inside LootJS.modifiers block:", String(e)); } }); })(); I don't know if this is the place to ask this, I have asked this same question in reddit but no one replied, maybe due to this issue being too technical. Please help me with this.