Created
February 9, 2026 01:59
-
-
Save sorcerykid/74969e0b3fb9c55bbf5901908f8e31a7 to your computer and use it in GitHub Desktop.
Compare map.sqlite databases and output a list of changed nodes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Usage: lua compare.lua | |
| -- License: MIT License | |
| package.path = "/home/minetest/maplib/?.lua;" .. package.path | |
| local maplib = require( "maplib" ) | |
| local config = dofile( "config.lua" ) | |
| --------------------------------------- | |
| local function printf( ... ) | |
| print( string.format( ... ) ) | |
| end | |
| local function compare_blocks( index, new_block, old_block ) | |
| local diff_lines = { } | |
| local old_node_list = old_block.get_node_list( ) | |
| local old_nodename_map = old_block.nodename_map | |
| local new_node_list = new_block.get_node_list( ) | |
| local new_nodename_map = new_block.nodename_map | |
| for idx, new_node in ipairs( new_node_list ) do | |
| local old_node = old_node_list[ idx ] | |
| local old_node_name = old_nodename_map[ old_node.id ] | |
| local new_node_name = new_nodename_map[ new_node.id ] | |
| if new_node_name ~= old_node_name then | |
| local pos = maplib.decode_node_pos( idx, index ) | |
| table.insert( diff_lines, string.format( "\t{ pos = { x = %d, y = %d, z = %d }, before = \"%s\", after = \"%s\" },", | |
| pos.x, pos.y, pos.z, old_node_name, new_node_name ) ) | |
| end | |
| end | |
| if #diff_lines > 0 then | |
| local logfile = assert( io.open( "output/" .. index .. ".txt", "w" ) ) | |
| logfile:write( "return {\n" ) | |
| for i, v in ipairs( diff_lines ) do | |
| logfile:write( v, "\n" ) | |
| end | |
| logfile:write( "}\n" ) | |
| logfile:close( ) | |
| end | |
| return #diff_lines | |
| end | |
| ----------------------------------------- | |
| local oldmap_db = MapDatabase( config.oldmap_path, false ) | |
| local newmap_db = MapDatabase( config.newmap_path, false ) | |
| if config.search_area then | |
| print( "Creating cache..." ) | |
| newmap_db.create_cache( false ) | |
| end | |
| print( "Comparing databases..." ) | |
| local iterator = config.search_area and | |
| newmap_db.iterate_area( config.search_area ) or | |
| newmap_db.iterate( ) | |
| for index, new_block in iterator do | |
| local old_block = oldmap_db.get_mapblock( index ) | |
| if not old_block then | |
| printf( "[WARNING] Missing block %d in old database!", index ) | |
| else | |
| local diff_count = compare_blocks( index, new_block, old_block ) | |
| if diff_count > 0 then | |
| printf( "[INFO] Block %d differs (%d nodes changed).", index, diff_count ) | |
| else | |
| printf( "[INFO] Block %d matches.", index ) | |
| end | |
| end | |
| end | |
| print( "Done." ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| return { | |
| oldmap_path = "oldmap.sqlite", | |
| newmap_path = "newmap.sqlite", | |
| search_area = MapArea( { x = -2, y = -2, z = -2 }, { x = 2, y = 2, z = 2 } ), | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local list = minetest.get_dir_list( "output", false ) | |
| minetest.after( 0, function ( ) | |
| for i, v in ipairs( list ) do | |
| local diff = dofile( "output/" .. v ) | |
| -- use the first node position to forceload the mapblock | |
| minetest.forceload_block( diff[ 1 ].pos, true ) | |
| for ii, vv in ipairs( diff ) do | |
| if vv.after == "air" then | |
| minetest.set_node( vv.pos, { name = "wool:red" } ) | |
| elseif vv.before == "air" then | |
| minetest.set_node( vv.pos, { name = "wool:green" } ) | |
| else | |
| minetest.set_node( vv.pos, { name = "wool:yellow" } ) | |
| end | |
| local meta = minetest.get_meta( vv.pos ) | |
| meta:set_string( "infotext", | |
| minetest.pos_to_string( vv.pos ) .. "\n" .. vv.before .. " -> " .. vv.after ) | |
| end | |
| minetest.forceload_free_block( diff[ 1 ].pos, true ) | |
| end | |
| end ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment