You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
otherwise when some other task is prioritized, dwarves will drop what they are currently doing. this will hopefully allow miners to mine without interruption, even without prioritizing mining jobs (which is usually a bad idea due to their volume)
Tasks:
Create JOB_TAKEN event for EventManager and fire when detected
Pipe JOB_TAKEN event through eventful
react to onJobTaken() in prioritize, prioritizing the job unconditionally
But isn't this bad if all your dwarves are doing pointless jobs that have been given high priority, and you'd, for example, desperately need a lever to be pulled? Or when something else that's kind of urgent shows up?
Mining jobs and some others have those numbered priority designations one through seven, so maybe that should be taken into account when prioritizing taken jobs?
I tried what I proposed here and it wasn't very effective.
The problem is that we don't have any granularity to set priority. It's either default (mostly ineffective) priority, or it's super high priority that beats everything else out and can interrupt other jobs. there's nothing in between.
What if you were to prioritize all taken jobs conditionally? Like pick a default stance (prioritize/skip prioritization) and then a way to specify exceptions to that rule. Then it'd have to do a check for every job, to see if you want it priorized or not. You could pick mining for high priority when it's imperative you get your digging done uninterrupted. If all other jobs are left on normal priority, it wouldn't be a miner who abandons their job.
We can prioritize our prioritization, so to speak, but I don't think that would solve the job interruption problem. I think the fundamental issue is that prioritize depends on there being only an appropriate number of dwarves that can do each type of job (so the "blast radius" of setting the do_now flag is reduced). The "everyone does this" approach of the work details system is very much at odds with this requirement.
I think ideally we would be adjusting the algorithm DF uses to prioritize jobs internally, using small increments, instead of using the sledgehammer-style do_now flag. Of course, if we knew how to be more subtle, I probably would have written prioritize to take that approach in the first place.
I know the overall job selection algorithm is on @Putnam3145 's radar. It could be that prioritize will just become obsolete before we come up with a good fix.
Job assignment is a per-tick auction. Each pass, DF pushes a job_applicationst{unit, posting_index, value} per candidate into a 2000-node binary heap in job_handler and the highest value wins the posting. The pass completes inside the tick (~0.1-0.5 ms), which is why the heap always looks empty from Lua.
Observed value bands (additive score):
~value
meaning
9.5k-15k
baseline bid (not labor-eligible / distant)
30k-170k
distance/labor-tuned bid
~1.05M
continuation bonus when a unit re-bids its current job type — the existing "stay on task" weight
~20M
do_now flag on the job, or unit-sourced needs jobs (Sleep etc.)
So the granularity problem myk002 described is real: do_now is a flat +20,000,000 for every bidder on the posting — it beats the ~1M continuation bonus but has no per-unit targeting, and unit-sourced need jobs live in the same band, which is why prioritized jobs still lose to food/drink/sleep. Separately, much of the visible "interruption" isn't preemption at all but claim races (a unit en route loses the posting to a faster claimer and re-evaluates) and needs thresholds.
On granularity: since value is additive, a bounded bonus term is mechanically possible in principle — but the heap is populated and drained entirely inside the pass, so scripts can't touch individual applications. A fix would need a hook/interpose point in the scorer (worldst::handle_job_applications per maintainer knowledge) — e.g. a small per-job bonus field consulted during application construction, sitting between baseline and the continuation bonus. Happy to dig further if that direction is wanted.
Related: #5954 adds a do_now toggle at building designation time, which covers the "make this one building urgent" case without churning the rest of the queue.
Activity
wsfsbvchr commentedon Apr 25, 2023
But isn't this bad if all your dwarves are doing pointless jobs that have been given high priority, and you'd, for example, desperately need a lever to be pulled? Or when something else that's kind of urgent shows up?
Mining jobs and some others have those numbered priority designations one through seven, so maybe that should be taken into account when prioritizing taken jobs?
myk002 commentedon Apr 25, 2023
I tried what I proposed here and it wasn't very effective.
The problem is that we don't have any granularity to set priority. It's either default (mostly ineffective) priority, or it's super high priority that beats everything else out and can interrupt other jobs. there's nothing in between.
wsfsbvchr commentedon Apr 25, 2023
What if you were to prioritize all taken jobs conditionally? Like pick a default stance (prioritize/skip prioritization) and then a way to specify exceptions to that rule. Then it'd have to do a check for every job, to see if you want it priorized or not. You could pick mining for high priority when it's imperative you get your digging done uninterrupted. If all other jobs are left on normal priority, it wouldn't be a miner who abandons their job.
myk002 commentedon Apr 25, 2023
We can prioritize our prioritization, so to speak, but I don't think that would solve the job interruption problem. I think the fundamental issue is that
prioritizedepends on there being only an appropriate number of dwarves that can do each type of job (so the "blast radius" of setting thedo_nowflag is reduced). The "everyone does this" approach of the work details system is very much at odds with this requirement.I think ideally we would be adjusting the algorithm DF uses to prioritize jobs internally, using small increments, instead of using the sledgehammer-style
do_nowflag. Of course, if we knew how to be more subtle, I probably would have writtenprioritizeto take that approach in the first place.I know the overall job selection algorithm is on @Putnam3145 's radar. It could be that
prioritizewill just become obsolete before we come up with a good fix.Alistair-Afton commentedon Sep 18, 2026
Mechanism data that may help here (verified on 53.16, details in DFHack/df_misc#90 and field docs in DFHack/df-structures#908):
Job assignment is a per-tick auction. Each pass, DF pushes a
job_applicationst{unit, posting_index, value}per candidate into a 2000-node binary heap injob_handlerand the highestvaluewins the posting. The pass completes inside the tick (~0.1-0.5 ms), which is why the heap always looks empty from Lua.Observed
valuebands (additive score):do_nowflag on the job, or unit-sourced needs jobs (Sleep etc.)So the granularity problem myk002 described is real:
do_nowis a flat +20,000,000 for every bidder on the posting — it beats the ~1M continuation bonus but has no per-unit targeting, and unit-sourced need jobs live in the same band, which is why prioritized jobs still lose to food/drink/sleep. Separately, much of the visible "interruption" isn't preemption at all but claim races (a unit en route loses the posting to a faster claimer and re-evaluates) and needs thresholds.On granularity: since
valueis additive, a bounded bonus term is mechanically possible in principle — but the heap is populated and drained entirely inside the pass, so scripts can't touch individual applications. A fix would need a hook/interpose point in the scorer (worldst::handle_job_applicationsper maintainer knowledge) — e.g. a small per-job bonus field consulted during application construction, sitting between baseline and the continuation bonus. Happy to dig further if that direction is wanted.Related: #5954 adds a
do_nowtoggle at building designation time, which covers the "make this one building urgent" case without churning the rest of the queue.