Lymkwi / python-minetest

A python library to manipulate minetest's files
6 stars 3 forks source link

loaded blocks still trigger on_generated() #13

Open ghost opened 8 years ago

ghost commented 8 years ago

When a block is loaded into the database, shouldn't minetest then ignore those blocks for on_generated() callbacks? it is confusing because on_generated() operates on a chunk which is 5x5x5 blocks but I just wonder what minetest does to mark blocks as completely generated so that they will be passed over by on_generated()

Lymkwi commented 8 years ago

what minetest does to mark blocks as completely generated so that they will be passed over by on_generated()

Minetest uses a bitmask to determine some informations about a mapblock

u8 flags

  • Flag bitmasks:
    • 0x01: is_underground: Should be set to 0 if there will be no light obstructions above the block. If/when sunlight of a block is updated and there is no block above it, this value is checked for determining whether sunlight comes from the top.
    • 0x02: day_night_differs: Whether the lighting of the block is different on day and night. Only blocks that have this bit set are updated when day transforms to night.
    • 0x04: lighting_expired: If true, lighting is invalid and should be updated. If you can't calculate lighting in your generator properly, you could try setting this 1 to everything and setting the uppermost block in every sector as is_underground=0. I am quite sure it doesn't work properly, though.
    • 0x08: generated: True if the block has been generated. If false, block is mostly filled with CONTENT_IGNORE and is likely to contain eg. parts of trees of neighboring blocks.

By default an empty mapblock should have 0x08 and 0x04 (so 0xb, 0d12), to tell that it's generated and force minetest to calculate the light again. I just fixed a stupid mistake which gave empty mapblocks none of those : https://github.com/LeMagnesium/python-minetest/commit/faffd8bf25a541557fd986952d18a8f32da05fda

0-afflatus commented 8 years ago

Slightly OT: I'm chasing large dark areas in my map. Would it be possible to do something like: if 0x08 and not 0x01 then set 0x04 to force lighting updates over the whole map or defined area? Can start a new thread for this if it's a reasonable idea.

Lymkwi commented 8 years ago

Would it be possible to do something like: if 0x08 and not 0x01 then set 0x04 to force lighting updates over the whole map or defined area?

The documentation of world_format.txt says it would most likely not work to force 0x04 in any case. For you map, you could try something like that (with latest version of the library, fresh from git):

import libminetest.map

vessel = libminetest.map.MapVessel("map.sqlite")
for i in vesse.get_all_mapblock_ids():
    m = vessel.load(i)
    bmask = vessel.get_bitmask()
    #bmask = vessel.bitmask otherwise, if no get_bitmask method
    if bmask & 8 and not bmask & 1:
        m.set_bitmask(bmask | 4)
    vessel.write(m.implode())

vessel.commit()
ghost commented 8 years ago

if someone finds a solution to the dark blocks issue let me know. the only solution I have found seems to DEPEND on this issue not being fixed: that is to add the following lines to init.lua of this or any other active mod (perhaps these lines could be added to https://github.com/LeMagnesium/python-minetest/blob/master/tools/python_minetest/init.lua ):

-- Set mapgen parameters
minetest.register_on_mapgen_init(function(mgparams)
    minetest.set_mapgen_params({mgname="singlenode", flags="nolight"})
end)
minetest.register_on_generated(function(minp, maxp, seed)
    local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
    vm:calc_lighting()
    vm:write_to_map()
    --vm:update_liquids()
end)