• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

A generic framework for programmatic modification of OTBM files

Forby

Veteran OT User
Joined
Jul 24, 2011
Messages
128
Reaction score
256
Location
The Lost Lands
The otbm2json library written for NodeJS can assist with the programmatic modification of OTBM map files. This can be very useful in when you want to make a logical change to your map data.

OTBM files are parsed to an intermediary JSON structure that is easily modified using a script. This modified JSON structure can then be converted back to OTBM with all modifications in place. Please see the GitHub repository for more information and examples.

Inconcessus/OTBM2JSON
 
Wow this is a very good contribution, i have a question?, i it posible to edit the map in real time?, i mean, when the map is loaded in the client, then you want to make a modification, then it loads the data in the running server. Is that posible?.

Thank you.
 
Wow this is a very good contribution, i have a question?, i it posible to edit the map in real time?, i mean, when the map is loaded in the client, then you want to make a modification, then it loads the data in the running server. Is that posible?.

Thank you.

This wouldn't just work out of bxo. This framework takes care of changing the OTBM, and that can be done dynamically. But you would have to be able to continuously read the map file while the server is running. I don't think that is something a lot of servers do. They read the map once and keep it in memory.
 
Hiho @Forby, I was thinking about using it to make map conversions, like [OTClient] Converting maps from different versions/protocols and Lua - Need more efficiency in a script, challenge for knowledgeable, test your skills., and randomizing some ids and fixing some borders/tiles along the way. My doubt before venturing myself into it (and spamming you with questions) is if it would be able to handle it and do it in a timely manner. I tried to generate a 4096x4096 map with OTMapGen and after some time running I got a memory error.
 
Last edited by a moderator:
Hiho @Forby, I was thinking about using it to make map conversions, like [OTClient] Converting maps from different versions/protocols and Lua - Need more efficiency in a script, challenge for knowledgeable, test your skills., and randomizing some ids and fixing some borders/tiles along the way. My doubt before venturing myself into it (and spamming you with questions) is if it would be able to handle it and do it in a timely manner. I tried to generate a 4096x4096 map with OTMapGen and after some time running I got a memory error.

NodeJS can be quite fast but and memory efficient. It depends a lot on the implementation, and mine is pretty liberal with memory usage. I wouldn't worry so much about the computational time and memory, unless you have a very, very large map.
 
Could be a bug in the library.. I will have a look later today
Gimme some more help, the exemple files doesn't contain a tile with itens but without a tile item, how would it look?
 
I think it's ok to be honest, but there was a bug in a function in OTBM2JSON. This should be fixed now:

Fix bug in removing escape characters · Inconcessus/OTBM2JSON@a4a913e

Try updating and see if it goes better..

Maybe also check

if(!x.tiles) return;

because somehow a tile area may have zero children.. that will get rid of the forEach of undefined.
 
Last edited by a moderator:
My script for that library. Replaces items by ID to other item ID:
PHP:
const otbm2json = require("./otbm2json");

// FROM_ID: TO_ID
let replaceArray = {
    2195: 123, // replaces 2195 with 123
};
// from 836 to 850 replaces with 1036 to 1050
for (let i = 836; i <= 850; i++) {
    replaceArray[i] = i + 200;
}
// from 1500 to 1550 replaces with 1600
for (let i = 1500; i <= 1550; i++) {
    replaceArray[i] = 1600;
}
const mapData = otbm2json.read("before.otbm");

function replaceItem(itemid) {
    return replaceArray[itemid] ? replaceArray[itemid] : itemid;
}

function replaceItemRecursive(item) {
    if (item.type === otbm2json.HEADERS.OTBM_ITEM) {
        item.id = replaceItem(item.id);
        if (item.content && item.content.length) {
            item.content.forEach(function (containerItem) {
                replaceItemRecursive(containerItem)
            });
        }
    }
}

// Go over all nodes
mapData.data.nodes.forEach(function (n) {
    n.features.forEach(function (e) {
        if (e.type !== otbm2json.HEADERS.OTBM_TILE_AREA) return;
        e.tiles.forEach(function (tile) {
            if (tile.type !== otbm2json.HEADERS.OTBM_TILE) return;

            tile.tileid = replaceItem(tile.tileid);
            if (tile.items && tile.items.length) {
                tile.items.forEach(function (item) {
                    replaceItemRecursive(item)
                });
            }
        });
    });
});

// Write the output to OTBM using the library
otbm2json.write("after.otbm", mapData);
Replaces ground items, items, containers and items inside containers.

My friend had 2 maps made using other .otb versions (client 11+) and wanted to copy some parts of map from one to other. This script saved him a lot of time.
 
Back
Top