Fire process...

deivan
Member
 
Posts: 452
Joined: Fri Feb 15, 2013 10:16

Fire process...

by deivan » Fri Feb 15, 2013 10:39

Hello.

Well, I installed the mod flamethrower and my first idea, burn down all the vine and bamboo. This two plantas start to growing and never end, I have many together growing to sky, ok...

I put fire in all and now the fire process is making me stuck, I run, I do actions, but the game don't is running, if I drop some the item don't leave my inventory, after some minutes, sometimes, the game undo my actions, the map don't is loaded when I move, I am stuck in the loaded area...

My point is, the core of the game need a process control to block a process when this one try eat all memory or process time. I don't say the machine processor but the in game time cycle... The time is running, I see the sun running in the sky, but the game is halted in many ways... :-/

Is it.
---------
Another thing... I have a small proposal for a change for the torch who make this ignite things when drop near flamable things. This "bug" make me lave this idea. :-/
Last edited by deivan on Fri Feb 15, 2013 10:45, edited 1 time in total.
 

deivan
Member
 
Posts: 452
Joined: Fri Feb 15, 2013 10:16

by deivan » Fri Feb 15, 2013 11:02

Ok, testing...
-*-
You only removed from the ignition group... -.-

I don't need remove this function from the fire, I only need the correct operation of the process. Don't is my idea of fix. Anyway I already detected this fix when I put my city in fire (have many wood) and changed the file to make all fire die, after I reverted the file.
Last edited by deivan on Fri Feb 15, 2013 11:15, edited 1 time in total.
 

User avatar
Calinou
Member
 
Posts: 3124
Joined: Mon Aug 01, 2011 14:26
GitHub: Calinou
IRC: Calinou
In-game: Calinou

by Calinou » Fri Feb 15, 2013 11:50

deivan wrote:My point is, the core of the game need a process control to block a process when this one try eat all memory or process time.


Properly made mods don't use 100% of the memory or processor (except for some hand made operations, such as removing all entities).
 

deivan
Member
 
Posts: 452
Joined: Fri Feb 15, 2013 10:16

by deivan » Fri Feb 15, 2013 14:24

Don't is a mod problem, is? The fire mod is the cause then... But I thinking in some type of engine problem. I need tools to debug it, tools in the game core. :-/
-*-
My point is, the game core need protect yourself or any mod error, small, very small, make all halt. :-/
Last edited by deivan on Fri Feb 15, 2013 14:25, edited 1 time in total.
 

deivan
Member
 
Posts: 452
Joined: Fri Feb 15, 2013 10:16

by deivan » Sat Feb 16, 2013 11:43

Ok. I have a alternative solution (without change the c++ code...)

In the script fire I put a wait time before the igniting process...

In "minetest.register_abm({"

I put this line in the first line of the action:
minetest.after(5,function() print("Starting at (".. tostring(p0.x) .. " " .. tostring(p0.y) .. " " .. tostring(p0.z) .. ")") end)

Then what it do? This small change make all flames started wait for 5 seconds before ignite some node in your are, then this process is halted for 5s don't making the system halt (strong delay, but dont crash).

Ok, here I changed de fire script and is working very well.

Full code of init.lua from fire:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- minetest/fire/init.lua
minetest.register_node("fire:basic_flame", {
    description = "Fire",
    drawtype = "plantlike",
    tiles = {{
        name="fire_basic_flame_animated.png",
        animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
    }},
    inventory_image = "fire_basic_flame.png",
    light_source = 14,
    groups = {igniter=2,dig_immediate=3},
        --groups = {dig_immediate=3},
    drop = '',
    walkable = false,
    buildable_to = true,
    damage_per_second = 4,
   
    after_place_node = function(pos, placer)
        fire.on_flame_add_at(pos)
    end,
   
    after_dig_node = function(pos, oldnode, oldmetadata, digger)
        fire.on_flame_remove_at(pos)
    end,
})

fire = {}
fire.D = 6
-- key: position hash of low corner of area
-- value: {handle=sound handle, name=sound name}
fire.sounds = {}

function fire.get_area_p0p1(pos)
    local p0 = {
        x=math.floor(pos.x/fire.D)*fire.D,
        y=math.floor(pos.y/fire.D)*fire.D,
        z=math.floor(pos.z/fire.D)*fire.D,
    }
    local p1 = {
        x=p0.x+fire.D-1,
        y=p0.y+fire.D-1,
        z=p0.z+fire.D-1
    }
    return p0, p1
end

function fire.update_sounds_around(pos)
    local p0, p1 = fire.get_area_p0p1(pos)
    local cp = {x=(p0.x+p1.x)/2, y=(p0.y+p1.y)/2, z=(p0.z+p1.z)/2}
    local flames_p = minetest.env:find_nodes_in_area(p0, p1, {"fire:basic_flame"})
    --print("number of flames at "..minetest.pos_to_string(p0).."/"
    --        ..minetest.pos_to_string(p1)..": "..#flames_p)
    local should_have_sound = (#flames_p > 0)
    local wanted_sound = nil
    if #flames_p >= 9 then
        wanted_sound = {name="fire_large", gain=1.5}
    elseif #flames_p > 0 then
        wanted_sound = {name="fire_small", gain=1.5}
    end
    local p0_hash = minetest.hash_node_position(p0)
    local sound = fire.sounds[p0_hash]
    if not sound then
        if should_have_sound then
            fire.sounds[p0_hash] = {
                handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}),
                name = wanted_sound.name,
            }
        end
    else
        if not wanted_sound then
            minetest.sound_stop(sound.handle)
            fire.sounds[p0_hash] = nil
        elseif sound.name ~= wanted_sound.name then
            minetest.sound_stop(sound.handle)
            fire.sounds[p0_hash] = {
                handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}),
                name = wanted_sound.name,
            }
        end
    end
end

function fire.on_flame_add_at(pos)
    --print("flame added at "..minetest.pos_to_string(pos))
    fire.update_sounds_around(pos)
end

function fire.on_flame_remove_at(pos)
    --print("flame removed at "..minetest.pos_to_string(pos))
    fire.update_sounds_around(pos)
end

function fire.find_pos_for_flame_around(pos)
    return minetest.env:find_node_near(pos, 1, {"air"})
end

function fire.flame_should_extinguish(pos)
    --return minetest.env:find_node_near(pos, 1, {"group:puts_out_fire"})
    local p0 = {x=pos.x-2, y=pos.y, z=pos.z-2}
    local p1 = {x=pos.x+2, y=pos.y, z=pos.z+2}
    local ps = minetest.env:find_nodes_in_area(p0, p1, {"group:puts_out_fire"})
    return (#ps ~= 0)
end

-- Ignite neighboring nodes
minetest.register_abm({
    nodenames = {"group:flammable"},
    neighbors = {"group:igniter"},
    interval = 1,
    chance = 2,
    action = function(p0, node, _, _)
                minetest.after(5,function() print("Starting at (".. tostring(p0.x) .. " " .. tostring(p0.y) .. " " .. tostring(p0.z) .. ")") end)
        -- If there is water or stuff like that around flame, don't ignite

        if fire.flame_should_extinguish(p0) then
            return
        end
        local p = fire.find_pos_for_flame_around(p0)
        if p then
            minetest.env:set_node(p, {name="fire:basic_flame"})
            fire.on_flame_add_at(p)
        end
    end,
})

-- Rarely ignite things from far
minetest.register_abm({
    nodenames = {"group:igniter"},
    neighbors = {"air"},
    interval = 2,
    chance = 10,
    action = function(p0, node, _, _)
        local reg = minetest.registered_nodes[node.name]
        if not reg or not reg.groups.igniter or reg.groups.igniter < 2 then
            return
        end
        local d = reg.groups.igniter
        local p = minetest.env:find_node_near(p0, d, {"group:flammable"})
        if p then
            -- If there is water or stuff like that around flame, don't ignite
            if fire.flame_should_extinguish(p) then
                return
            end
            local p2 = fire.find_pos_for_flame_around(p)
            if p2 then
                minetest.env:set_node(p2, {name="fire:basic_flame"})
                fire.on_flame_add_at(p2)
            end
        end
    end,
})

-- Remove flammable nodes and flame
minetest.register_abm({
    nodenames = {"fire:basic_flame"},
    interval = 1,
    chance = 2,
    action = function(p0, node, _, _)
            -- If there is water or stuff like that around flame, remove flame
        if fire.flame_should_extinguish(p0) then
            minetest.env:remove_node(p0)
            fire.on_flame_remove_at(p0)
            return
        end
        -- Make the following things rarer
        if math.random(1,3) == 1 then
            return
        end
        -- If there are no flammable nodes around flame, remove flame
        if not minetest.env:find_node_near(p0, 1, {"group:flammable"}) then
            minetest.env:remove_node(p0)
            fire.on_flame_remove_at(p0)
            return
        end
        if math.random(1,4) == 1 then
            -- remove a flammable node around flame
            local p = minetest.env:find_node_near(p0, 1, {"group:flammable"})
            if p then
                -- If there is water or stuff like that around flame, don't remove
                if fire.flame_should_extinguish(p0) then
                    return
                end
                minetest.env:remove_node(p)
                nodeupdate(p)
            end
        else
            -- remove flame
            minetest.env:remove_node(p0)
            fire.on_flame_remove_at(p0)
        end
    end,
})
 

deivan
Member
 
Posts: 452
Joined: Fri Feb 15, 2013 10:16

by deivan » Mon Feb 25, 2013 11:56

This type of thing don't halt my server anymore...
Image
 


Return to Minetest Problems

Who is online

Users browsing this forum: No registered users and 9 guests

cron