Upgrade System
Upgrade state is stored per furnace. Different furnaces owned by the same player may have different appliance types, slot levels, speed, fuel efficiency, and permanent abilities. There are no player-wide global upgrades.
Player workflow#
- Run
/kfto open the main menu. - Click the upgrade button to enter furnace-selection mode.
- Click the furnace to manage and open its upgrade menu.
- Click an appliance type, level upgrade, or permanent ability to purchase it.
Players can only purchase through the menu and cannot bypass upgrades.yml prices with a text command. Purchase transactions are serialized per player, so rapid clicks cannot withdraw the same balance concurrently.
Purchasable items#
| Item | Initial state | Purchase rule |
|---|---|---|
| Furnaces 2 through 10 | Only the first regular furnace is free | Charged using the number of the furnace being created |
| Furnace, blast furnace, or smoker type | FURNACE |
Charged whenever switching to a different target type |
| Five level upgrades | Level 1 |
Only the next level can be purchased, up to level 6 |
| Three permanent abilities | Locked | Each ability is purchased once per furnace |
Selecting the current appliance type, an already unlocked ability, or a maxed level does not charge. A type switch also requires every input, fuel, and output slot to be empty and all active burn time to be exhausted.
Five level effects#
| Configuration key | Runtime effect |
|---|---|
input_slot |
The level is the usable input-slot count; the engine selects the first valid recipe in slot order |
fuel_slot |
The level is the usable fuel-slot count; ignition selects the first valid fuel in slot order |
output_slot |
The level is the usable output-slot count; results merge into a similar stack first, then use the first empty slot |
fuel_efficiency |
actual burn duration = base duration × burn_duration_multiplier |
smelting_speed |
actual cooking duration = base duration ÷ speed_multiplier |
Multiple input slots share one cooking progress and fuel supply; they do not process in parallel. An active cycle pins its recipe, input slot, result, experience, and duration. A speed purchase or /kf reload does not change an active cycle. Fuel efficiency likewise applies only to fuel ignited afterward and does not recalculate the active remainder.
Players can only upgrade and cannot downgrade. If an administrator lowers a slot level while a slot that would become locked still contains an item, the change is rejected until that slot is emptied.
Three permanent abilities#
Offline smelting#
After offline_smelting is unlocked, that furnace continues advancing by absolute time while its owner is offline. A furnace without the ability freezes its time baseline offline and resumes from a new baseline when the owner returns, without processing the paused interval.
A long offline interval remains limited by max-settlements-per-advance and may require several engine refreshes to catch up completely.
Automatic output delivery#
After auto_output_delivery is unlocked, KaFurnace checks all furnaces owned by an online player every engine-interval-ticks on that player's entity thread:
- delivery only runs while the owner is online;
- unlocked output slots are processed in order;
- only the amount currently accepted by the player inventory is extracted;
- matching output experience is granted at the same time;
- output and experience that do not fit remain in their original output slot;
- every extraction waits for a critical database write.
Completion notification#
completion_notification records a completed batch after a furnace finishes at least one cycle and then has no valid input left to process. The owner receives that batch notification once while online. The claim is persisted immediately so refreshes and restarts do not send it repeatedly.
Invalid recipe items may remain in input slots. “Complete” means that no valid input can continue processing, not that every input slot is physically empty.
Payment and database transaction#
Every price selects vault or playerpoints in upgrades.yml. The order is fixed:
validate target and current state
-> check provider and balance
-> withdraw payment
-> mutate furnace state
-> wait for the critical database write
-> success
If the database commit fails, or a business condition changes after withdrawal, KaFurnace restores the previous furnace state and attempts one refund through the same provider. A failed refund writes a SEVERE audit entry containing the player UUID, provider, amount, and reason; an administrator must reconcile it manually.
A price of 0 still requires its provider and runs the complete transaction. Vault prices require Vault plus an Economy implementation because Vault does not store balances itself. PlayerPoints prices must be integers.
The bundled upgrades.yml uses both Vault and PlayerPoints. Before the first test, install both providers or change every priced entry to a provider available on the server and run /kf reload.
Administrator management#
Administrators can inspect or force state on an existing furnace owned by a target player:
/kf admin furnace <player|UUID> <1-10> get
/kf admin furnace <player|UUID> <1-10> set <property> <value>
/kf admin furnace <player|UUID> <1-10> reset <property>
set and reset bypass payment and sequential-level purchasing, but still enforce value ranges, non-empty locked-slot checks, and database persistence. These commands do not create a missing furnace. See Commands and Permissions for every property and permission.
Reload boundary#
/kf reload validates all new prices and multipliers before atomically replacing the active settings. Reload does not switch the database connection and does not rewrite active cooking or fuel durations. New prices apply to transactions started after reload completes.