Small changes concerning balance, gameplay, or graphics.
Furnaces, assembling machines, production chains.
This mod seems to override the productivity researches. For example, I had 80% productivity for steel plates through the mod before I did my first steel research. My thinking was that it should have increased the productivity to 90%. It seemed to do so for a few seconds, then it reset back to 80%. Did the second research to confirm and it did the same thing.
Not sure if this is intended or not.
This is unintended, and I'm currently working with another dev to see if we can get this to work properly (as well as play nicely with other mods that modify productivity)
Is it looking to be possible or does it just not play nicely with productivity bonuses? I too am hoping it can be resolved. Great mod otherwise!
I have an idea for research at minimum, but I've been busy with work. I'll try to get the idea implemented this weekend, but I don't know if there's a good way to make it play nicely with other mods. Research I can iterate through the different researches and just add them all up, but I'll spend some time thinking about it still.
I'm still working on it, but just like demonicpigg very busy with work.
I'm working on a completely new calculation model, that tracks previous levels, previous settings and research events, as well as allowing other mods to register with Progressive Productivity to ask for specific changes.
Based on these values, and with the old and new total, this model should in theory always be able to apply the right productivity values (P.P., requested modifications from outside, research, rouge changes from other mods). The only area of uncertainty will be the rouge changes from other mods, while those can be calculated and later displayed in the GUI, for technical reasons this mod will never be able to figure out who did those changes or why. We could consider writing them to the log files though.
This also will lay the groundwork for better compatibility with other mods, user overrides per item/fluid and per recipe and an UI overhaul.
Unfortunately, it takes quite some time and as I have the mod currently not even in a running state, and made it my main Factorio priority, I have been unable to play for about the last month or so. So I hope you can see I want to get this finished asap as well, I am dying to play again. :)
@demonicpigg, I hope to send you a pull request again, soon, until then, maybe this can give you some rough idea about how I have approached the thing:
calculation_model.lua:
---This module provides the calculation model for this mod.
---
---Handlers can be registered to be called whenever the model changes.
---
---The model is kept up to date automatically.
---@class (exact) CalculationModel
---@field calculation_products Dictionary<CalculationProduct> The products considered when calculating productivity bonuses.
---@field calculation_recipes Dictionary<CalculationRecipe> The recipes considered when calculating productivity bonuses.
---@field modification_requests ModificationRequests The modification requests that have been made.
---@field on_model_changed fun(subscriber: fun()) Registers a handler to be called when the model changes.
local calculation_model = {}
---@class (exact) CalculationProduct
---@field name string The name of the product.
---@field type "item" | "fluid" The type of the product.
---@field producing_recipes Dictionary<CalculationRecipe> The recipes that produce the product.
---@field current_level int The current production level of the product.
---@field next_level_requirement uint64|double The production amount required to reach the next level.
---@field produced uint64|double The amount of the product produced. (*A cached value.*)
---@class (exact) CalculationRecipe
---@field name string The name of the recipe.
---@field products Dictionary<CalculationProduct> The products that the recipe produces.
---@field current_level int The current productivity level of the recipe.
---@field productivity_bonus_from_requests float The sum of all non-rejected productivity bonus requests.
---@field productivity_bonus_from_technology float The productivity bonus from researched technologies.
---@field productivity_bonus_from_current_level float The productivity bonus from modules in the recipe.
---@field productivity_bonus_current_total float The total productivity bonus of the recipe.
(calculation_modifications.lua will need a separate reply, as this is getting too long)
calculation_modifications.lua:
---This module manages calculation modifications.
---
---It accepts requests to modify whether and how products and recipes are considered in calculations
---(e.g. ignoring products or recipes, or adjusting productivity bonuses).
---Players can decide to reject any request.
---Players can reject any request.
---The module provides the raw requests as well as the resulting effective outcomes.
---
---A remote interface is provided.
---Other mods can use it to request modifications.
---If a mod is removed, its requests are removed automatically.
---
---Handlers can be registered to be called whenever effective outcomes change.
---
---**NOTES:**
---- Players can reject specific requests, or all requests from a certain mod or for a certain reason.
---- Currently, only adding modification requests is supported; changes and removals might come later.
---- Access to the modification request interface is restricted to the remote interface, even for internal use.
--- This is mostly for testing and quality assurance, following the eat-your-own-dog-food approach.
--- - -- TODO: After successful testing, allow internal use of the interface and replace remote calls with direct usage.
---@class (exact) CalculationModifications
---@field requesting_mods Dictionary<RequestingMod> The mods that have requested modifications.
---@field registered_reasons Dictionary<RequestReason> The reasons registered for explaining modification requests to the player.
---@field requests ModificationRequests The modification requests.
---@field aggregated_requests AggregatedRequests The aggregated valid modification requests that should be applied.
local calculation_modifications = {
requesting_mods = {},
registered_reasons = {},
requests = {
product_ignore_requests = {},
recipe_ignore_requests = {},
recipe_product_ignore_requests = {},
recipe_productivity_bonus_adjustment_requests = {}
},
aggregated_requests = {
product_ignore_requests = {},
recipe_ignore_requests = {},
recipe_product_ignore_requests = {},
recipe_productivity_bonus_adjustment_requests = {}
}
}
--#region Type definitions
--#region Request sources and reasons
---Represents a mod that makes modification requests.
---@class (exact) RequestingMod
---@field name string The identifier of the requesting mod.
---@field display_name LocalisedString The display name of the requesting mod.
---@field rejected_by_player boolean Indicates whether the player wants all requests of this mod to be rejected.
---Represents a reason for a modification request.
---@class (exact) RequestReason
---@field name string The identifier of the request reason.
---@field display_text LocalisedString The display text of the request reason.
---@field provider RequestingMod The mod that registered the reason.
---@field rejected_by_player boolean Indicates whether the player wants all requests of this reason to be rejected.
--#endregion Request sources and reasons
--#region Modification Requests
---@class (exact) ModificationRequests
---@field product_ignore_requests Dictionary<Dictionary<ProductModificationRequest>> The products that have been requested to be ignored.
---@field recipe_ignore_requests Dictionary<Dictionary<RecipeModificationRequest>> The recipes that have been requested to be ignored.
---@field recipe_product_ignore_requests Dictionary<Dictionary<Dictionary<RemoveRecipeProductRequest>>> The products that have been requested to be ignored within specific recipes.
---@field recipe_productivity_bonus_adjustment_requests Dictionary<Dictionary<RecipeBonusProductivityRequest>> The bonus productivity adjustments that have been requested for certain recipes.
---Base class of a modification request.
---@class (exact) ModificationRequest
---@field requester RequestingMod The mod that requested the modification.
---@field reason RequestReason The reason for the modification request.
---@field rejected_by_player boolean Whether the modification request was rejected by the player.
---Represents a product modification request.
---@class (exact) ProductModificationRequest : ModificationRequest
---@field product_name string The name of the product to modify.
---@field product_type "item" | "fluid" The type of the product.
---Represents a recipe modification request.
---@class (exact) RecipeModificationRequest : ModificationRequest
---@field recipe_name string The name of the recipe to modify.
---Represents a request to remove a product from a recipe.
---@class (exact) RemoveRecipeProductRequest : ProductModificationRequest, RecipeModificationRequest
-- TODO: Consider some kind of product count miltiplicator/devider request, globally and per recipe.
---Represents a request to apply a productivity bonus to a recipe.
---
---Requested productivity bonus may be negative.
---Requested productivity bonuses are additive,
---meaning that if multiple mods request a bonus for the same recipe, the bonuses are added together.
---
---If the sum of all productivity bonus requests is negative, it will be treated as 0.
---@class (exact) RecipeBonusProductivityRequest : RecipeModificationRequest
---@field productivity_bonus float The productivity bonus to apply.
--#endregion Modification Requests
---@class (exact) AggregatedRequests
---@field product_ignore_requests Dictionary<true> The products that should be ignored.
---@field recipe_ignore_requests Dictionary<true> The recipes that should be ignored.
---@field recipe_product_ignore_requests Dictionary<Dictionary<true>> The products that should be ignored within specific recipes.
---@field recipe_productivity_bonus_adjustment_requests Dictionary<number> The bonus productivity adjustments that have been requested for certain recipes.
---@class (exact) ModificationRequestInterface
---@field set_mod_display_name fun(source_mod_display_name: LocalisedString)
---@field register_request_reason fun(source_mod_identifier: string, reason_name: string, reason_display_name?: LocalisedString) Registers a reason for ignore requests.
---@field ignore_item fun(source_mod_identifier: string, item_name: string, reason_name: string) Requests an item to not cause progressive productivity bonuses.
---@field ignore_fluid fun(source_mod_identifier: string, fluid_name: string, reason_name: string) Requests a fluid to not cause progressive productivity bonuses.
---@field ignore_recipe fun(source_mod_identifier: string, recipe_name: string, reason_name: string) Requests a recipe to not get progressive productivity bonuses.
---@field request_recipe_productivity_bonus fun(source_mod_identifier: string, recipe_name: string, productivity_bonus) Requests a recipe to have a productivity bonus.
--#endregion Type definitions
(I hit the wrong button.)
(I hit the wrong button.)