Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: dfhack: 200k+ FellTree jobs. How can I remove them?  (Read 1236 times)

rrauenza

  • Escaped Lunatic
    • View Profile
dfhack: 200k+ FellTree jobs. How can I remove them?
« on: April 16, 2017, 03:30:48 pm »


Related github thread:  https://github.com/DFHack/dfhack/issues/1076

I was looking into my FPS going down to 1 FPS.  I was guessing that maybe I had a FB walled off somewhere in the caverns... I think I'm wrong.  I think my root problem is I was playing with autochop and somehow it created 200K+ FellTree designations/jobs.  These designations don't show up on the screen and they don't show up in the in game job list.

They do, however, show up in the in memory job list:

[DFHack]# rb count = 0; df.world.job_list.each { |job|  if job.job_type == :FellTree then count += 1 end } ; puts count
228399
[DFHack]#

This, combined with autounsuspend.rb running every 5 ticks, was dropping my FPS to 1.

How can I find and remove these FellTree jobs?
Logged

rrauenza

  • Escaped Lunatic
    • View Profile
Re: dfhack: 200k+ FellTree jobs. How can I remove them?
« Reply #1 on: April 16, 2017, 03:43:31 pm »

Looping over the jobs, I dumped the job.pos ... .most have a zlevel of 151, but my game only has z level up to *139.


* Ah, I think I created a manual tree job and it also was at 151, so z levels don't map exactly...
« Last Edit: April 16, 2017, 05:32:33 pm by rrauenza »
Logged

rrauenza

  • Escaped Lunatic
    • View Profile
Re: dfhack: 200k+ FellTree jobs. How can I remove them?
« Reply #2 on: April 16, 2017, 07:03:18 pm »

Finally figured out how to clean up the jobs.

I first walked each FellTree jobs to see if any tiles were marked for FellTree.  None were.  So these jobs existed without a corresponding tile.

I cobbled together this, some of the code taken from advFort.lua:

Code: [Select]
function smart_job_delete( job )
    local gref_types=df.general_ref_type
    --TODO: unmark items as in job
    for i,v in ipairs(job.general_refs) do
        if v:getType()==gref_types.BUILDING_HOLDER then
            local b=v:getBuilding()
            if b then
                --remove from building
                for i,v in ipairs(b.jobs) do
                    if v==job then
                        b.jobs:erase(i)
                        break
                    end
                end
            else
                print("Warning: building holder ref was invalid while deleting job")
            end
        elseif v:getType()==gref_types.UNIT_WORKER then
            local u=v:getUnit()
            if u then
                u.job.current_job =nil
            else
                print("Warning: unit worker ref was invalid while deleting job")
            end
        else
            print("Warning: failed to remove link from job with type:",gref_types[v:getType()])
        end
    end
    --unlink job
    local link=job.list_link
    if link.prev then
        link.prev.next=link.next
    end
    if link.next then
        link.next.prev=link.prev
    end
-- Don't delete the ptrs because I think something still is hanging on to them.
    --link:delete()
    --finally delete the job
    --job:delete()
end

local job_link=df.global.world.job_list.next

while job_link do
    local job = job_link.item
job_link = job_link.next
if job and job.job_type == 9 then
dfhack.job.printJobDetails(job)
smart_job_delete(job)
end
end


I had to comment out the parts that actually freed the memory or the save crash -- my guess is there was a double free or something.  As long as the double linked list was trimmed, the save process saved the trimmed list.
Logged