PD Force Trade


Adds a Trade Radar that lets forces trade items via offers. Uses a Send Port and Receive Port and consumes configurable energy per trade.

Content
3 days ago
2.0
47
Logistics

Changelog

Version: 1.7.37
Date: 2026-01-27
  Changes:
    - Multiplayer safety: deterministic roboport selection for hidden requester (sorted + tie-break).
    - Multiplayer safety: deterministic iteration order when moving inventory contents (sorted keys instead of pairs()).

Version: 1.7.36
Date: 2026-01-27
  Changes:
    - Fix: when a Trade Radar is mined/destroyed, the Send/Receive Ports (including provider receive port) are now removed (on_radar_removed now calls destroy_ports_for_radar).

Version: 1.7.35
Date: 2026-01-27
  Changes:
    - Fix: provider Receive Port cleanup improved — on radar removal, the mod now removes the south port reliably (by name) and includes a safe fallback that deletes only non-minable active-provider logistic containers near the expected south position.

Version: 1.7.34
Date: 2026-01-27
  Changes:
    - Fix: provider Receive Port (active provider chest) now gets removed reliably by searching near the expected port positions (no force filter).

Version: 1.7.33
Date: 2026-01-27
  Changes:
    - Fix: removing a Trade Radar now deletes ALL nearby Send/Receive port entities with a wide sweep (prevents provider receive port being left behind).

Version: 1.7.32
Date: 2026-01-27
  Changes:
    - Fix: Provider Receive Port (active-provider chest) is now reliably removed when its radar is mined/destroyed (adds robust fallback area search).

Version: 1.7.31
Date: 2026-01-27
  Changes:
    - Fix: when a Trade Radar is mined/destroyed, its Send/Receive Ports are now removed as well.
    - Fix: hidden requester is removed when the last Trade Radar on a surface is removed (prevents leftover hidden entities).

Version: 1.7.30
Date: 2026-01-27
  Changes:
    - Fix: radar rescan now actually discovers all Trade Radars on all surfaces and re-spawns missing ports (multi-radar support).
    - Fix: repaired corrupted safe_refresh_force_ui implementation (prevents recursion / instability).

Version: 1.7.29
Date: 2026-01-27
  Changes:
    - Fix: locale file section headers are now unique (removes duplicate [item-name]/[entity-name] that prevented the game from loading).

Version: 1.7.28
Date: 2026-01-27
  Changes:
    - Fix: multiple Trade Radars now reliably spawn their Send/Receive ports (periodic rescan heals missing ports).
    - New: added "Trade Radar (Provider)" recipe/item that spawns an Active Provider Receive Port (south chest) so bots can automatically take received items.

Version: 1.7.27
Date: 2026-01-27
  Changes:
    - Change: canceling pending logistic requests now returns any already-delivered items to the Receive Ports (south chests) instead of the north ports.

Version: 1.7.26
Date: 2026-01-26
  Changes:
    - Fix: recovery message now correctly says Receive Ports (south chests).

Version: 1.7.25
Date: 2026-01-26
  Changes:
    - Change: "Recover stuck items" now moves recovered items to the Receive Ports (south chests) instead of the Send Ports.

Version: 1.7.24
Date: 2026-01-26
  Changes:
    - Fix: removed stray leftover GUI recovery code block that caused a load-time syntax error (and referenced undefined variables).

Version: 1.7.23
Date: 2026-01-26
  Changes:
    - Fix: quality handling now uses quality name strings for insert/remove/get counts (prevents crashes when recovering items).
    - Safety: "Recover stuck items" now recovers ONLY from Request Buffers (not escrow chests) to avoid breaking active offers.

Version: 1.7.22
Date: 2026-01-26
  Changes:
    - Fix: "Recover stuck items" / cancel recovery now uses slot-based transfers from hidden buffers/escrows to Send Ports (more reliable; preserves quality; avoids get_contents edge cases).

Version: 1.7.21
Date: 2026-01-26
  Changes:
    - Fix: cleaned up duplicated/leftover code in the GUI click handler that caused a load-time syntax error.

Version: 1.7.20
Date: 2026-01-26
  Changes:
    - New: "Recover stuck items" now moves items from hidden Request Buffers and Escrow chests into your Send Ports (south chests) so bots can collect them.
    - Change: Cancel pending logistic request now cancels requests and moves any delivered items into your Send Ports (no direct player refund).

Version: 1.7.16
Date: 2026-01-26
  Changes:
    - Fix: Cancel pending request no longer risks moving/migrating requester chests; it cancels requests on all Request Buffers and recovers delivered items so nothing is lost.
    - Fix: "Recover stuck items" now scans and recovers from ALL Request Buffers on the current surface (supports multiple/legacy buffers).

Version: 1.7.15
Date: 2026-01-26
  Changes:
    - Fix crash on "Recover stuck items": Request Buffer contents can include quality-aware entries; recovery now normalizes {name, quality, count} safely and refunds/spills without errors.

Version: 1.7.14
Date: 2026-01-26
  Changes:
    - Fix: wired up the new Cancel/Recover buttons (click handler).

Version: 1.7.13
Date: 2026-01-26
  Changes:
    - Added "Cancel pending request" button: cancels current logistic request and refunds any delivered items from the hidden Request Buffer back to the player.
    - Added "Recover stuck items" button: empties the hidden Request Buffer into the player inventory (spills overflow), so items never stay in limbo.

Version: 1.7.12
Date: 2026-01-26
  Changes:
    - UI: removed duplicate header label in the titlebar (frame caption already shows the title).

Version: 1.7.11
Date: 2026-01-26
  Changes:
    - UI polish: removed duplicate header and removed "(Experimental)" wording from visible UI/mod title.

Version: 1.7.10
Date: 2026-01-26
  Changes:
    - Fix: removed stray duplicated code at top of control.lua that caused `<eof> expected near 'end'` on load.

Version: 1.7.9
Date: 2026-01-26
  Changes:
    - Fix crash on save load (Factorio 2.0): on_load no longer writes to `storage`. State binding is now read-only on_load; migration runs only on_init/on_configuration_changed.

Version: 1.7.8
Date: 2026-01-26
  Changes:
    - Fix: Offers and History now persist correctly on Factorio 2.0 reloads. The mod now rebinds state to the CURRENT `storage` table on load and at the start of event handlers.
    - Prevents item loss caused by state being written to a stale (non-persistent) table reference.

Version: 1.7.7
Date: 2026-01-26
  Changes:
    - Fix persistence: removed legacy "rebuild offers from escrow combinators" calls that could wipe saved offers/history after reload.
    - Legacy rebuild now early-returns if no escrow combinators exist (prevents wiping persisted state).

Version: 1.7.6
Date: 2026-01-26
  Changes:
    - Fix: History now persists on Factorio 2.0 saves by always writing to `storage` (and migrating any old `global` data into `storage` once).

Version: 1.7.5
Date: 2026-01-26
  Changes:
    - Fix crash on Factorio 2.0: if `global` is nil, the mod now aliases `global` to `storage` (persistent state table).

Version: 1.7.4
Date: 2026-01-26
  Changes:
    - UI: renamed labels to "Your offer" / "You want".

Version: 1.7.3
Date: 2026-01-26
  Changes:
    - Fix crash on reload: removed illegal reassignment `global = global or {}` (Factorio provides `global`; reassigning can make it nil/empty).

Version: 1.7.2
Date: 2026-01-26
  Changes:
    - Fix crash on load: migrate_legacy_escrows is now forward-declared so on_configuration_changed can call it safely.

Version: 1.7.1
Date: 2026-01-26
  Changes:
    - History tab now refreshes when UI opens and when pressing Refresh.

Version: 1.7.0
Date: 2026-01-26
  Changes:
    - Escrow now uses a single shared chest per force per surface (stops escrow chests drifting sideways with higher IDs).
    - Added global transaction History tab (persists across save/load).
    - Migration: legacy per-offer escrow chests are merged into the shared escrow chest.

Version: 1.6.16
Date: 2026-01-26
  Changes:
    - Hidden Request Buffer chest is now truly invisible (uses empty animation sprites in 2.x).
    - Buffer prefers to be placed under the Trade Radar when the radar is inside logistic coverage; if the old buffer is far away it migrates (moves contents) to the radar.

Version: 1.6.15
Date: 2026-01-26
  Changes:
    - Accept: offered items no longer block on Receive Port capacity. If Receive Ports are full, remaining items overflow into the hidden Request Buffer (then flushed back to Send Ports).
    - Prevents "accept didn't work" due to limited receive chest capacity.

Version: 1.6.14
Date: 2026-01-26
  Changes:
    - Fix: insert_into_all_receive() was accidentally returning early, causing deliveries/trades to stall and leaving items in buffers.
    - Cleanup: after listing/completing trades, hidden requester buffers are flushed back into Send Ports so leftover requested items don't stay in the temporary buffer chest.

Version: 1.6.13
Date: 2026-01-25
  Changes:
    - Fix: accepting trades no longer 'moves payment into limbo' while waiting for delivery; payment is removed only when the trade can complete immediately.
    - Fix: accept now validates escrow + receive space first; includes rollback/refund safeguards.
    - Owner payment overflow goes to owner's hidden requester buffer (prevents loss if their Receive Ports are full).

Version: 1.6.12
Date: 2026-01-25
  Changes:
    - Fixed duplication/limbo when accepting offers with full Receive Ports: trade completion now waits until there is enough space for the full delivery (no partial inserts).
    - Payment is only transferred to the offer owner after the acceptor successfully receives the offered items.
    - Reduced spam: "Receive Ports full" message prints once per pending trade.

Version: 1.6.11
Date: 2026-01-25
  Changes:
    - Fixed crash after accepting offer: insert_into_all_receive() now always returns a number; delivered comparison no longer errors.

Version: 1.6.10
Date: 2026-01-25
  Changes:
    - Critical fix: accept/cancel no longer creates a new empty escrow chest. Existing escrow entities at the offer position are returned instead of nudging.
    - Accept pending no longer cancels offers when escrow is temporarily missing; it waits and retries (prevents item loss/limbo).

Version: 1.6.9
Date: 2026-01-25
  Changes:
    - UX: removed repeating pending warnings while logistic requests are still being fulfilled (messages now print once per pending action).

Version: 1.6.8
Date: 2026-01-25
  Changes:
    - Fixed crash during pending processing: forward-declared remove_from_all_send so remove_from_sources() doesn't call a nil global.

Version: 1.6.7
Date: 2026-01-25
  Changes:
    - Fix: offers no longer disappear when reopening the UI (escrow rebuild is now conditional and never wipes offers if no valid escrows are found).

Version: 1.6.6
Date: 2026-01-25
  Changes:
    - Fixed remaining cancel-offer crash: cancel handler now uses validate_offer()/resolve_surface() instead of game.surfaces[offer.escrow_surface].

Version: 1.6.5
Date: 2026-01-25
  Changes:
    - Fixed crash when canceling/accepting offers created in older versions: validates offer fields and safely resolves escrow surface before indexing game.surfaces.

Version: 1.6.4
Date: 2026-01-25
  Changes:
    - Stability: GUI refresh is now deterministic and wrapped in pcall to prevent crashes/desync.
    - Robustness: pending-offer finalization is wrapped in pcall; on error it refunds removed items to the Request Buffer.
    - Better feedback: prints full offer summary when auto-listed.

Version: 1.6.3
Date: 2026-01-25
  Changes:
    - Auto-listed offers now immediately appear in the UI (force-wide refresh when pending offers finalize).

Version: 1.6.2
Date: 2026-01-25
  Changes:
    - Fix: initialize pending offer queue globals (prevents nil counter errors).

Version: 1.6.1
Date: 2026-01-25
  Changes:
    - Added force-level pending offer queue that auto-lists offers once requested items arrive in the Request Buffer (more reliable than per-player pending actions).

Version: 1.5.7
Date: 2026-01-25
  Changes:
    - Fixed auto-request offers never listing: pending action completion now counts items delivered into the Request Buffer (hidden requester chest), not just Send Ports.

Version: 1.5.6
Date: 2026-01-25
  Changes:
    - Fix "radar limbo": refunds and internal flows now return items to the Request Buffer (hidden requester chest) first, then Receive Ports.
    - Pending actions no longer double-count Request Buffer items; improves consistency and prevents disappearing offers.

Version: 1.5.5
Date: 2026-01-25
  Changes:
    - Fix: items delivered to the Request Buffer (hidden requester chest) are now counted and consumed when creating/accepting offers.
    - Fix: pending auto-request actions now complete correctly and list offers once bots deliver items.
    - Fix: refunds now return items to the Request Buffer first to avoid 'radar limbo' when ports are blocked.

Version: 1.5.4
Date: 2026-01-25
  Changes:
    - Fixed crash in 1.5.3: REQUESTER_CHEST constant was missing (caused find_non_colliding_position() 'name' parameter error).

Version: 1.5.3
Date: 2026-01-25
  Changes:
    - Auto-request fix: hidden requester is now guaranteed to be placed inside a logistic network (uses find_logistic_network_by_position + spiral search near roboport).

Version: 1.5.2
Date: 2026-01-25
  Changes:
    - Auto-request reliability: hidden requester is now placed at the nearest roboport anywhere on the surface (not limited radius).
    - Adds clear guidance when Logistic System tech is missing or no roboport exists for the force on that surface.

Version: 1.5.1
Date: 2026-01-25
  Changes:
    - Fixed a data stage syntax error introduced in 1.5.0 (hidden requester prototype definition).

Version: 1.5.0
Date: 2026-01-25
  Changes:
    - Fixed auto-request on Factorio 2.x: hidden requester chest is now a real requester chest (not placeable-off-grid, no zero collision), placed safely near a roboport with find_non_colliding_position.
    - Hidden requester is now invisible via a transparent sprite, but keeps full logistic request functionality.

Version: 1.4.2
Date: 2026-01-25
  Changes:
    - Improved logistic request compatibility: brute-force search for logistic point indices (0..20) and clearer failure reasons.

Version: 1.4.1
Date: 2026-01-25
  Changes:
    - Fixed auto-request debug always showing 'unknown': capture (ok, reason) return values from set_request() in Deposit/List and Accept paths.

Version: 1.4.0
Date: 2026-01-25
  Changes:
    - Fixed auto-request not working: correct LuaEntity.get_logistic_point() call signature (Factorio 2.x).
    - More robust requester logistic section detection (get_requester_point / section APIs).
    - Auto-request debug now prints a real reason (never nil).

Version: 1.3.9
Date: 2026-01-25
  Changes:
    - Auto-request debug: prints why logistic request could not be created (classic requester API vs logistic section API).
    - Forces logistic request section to manual before setting slots (Factorio 2.x compatibility).

Version: 1.3.8
Date: 2026-01-25
  Changes:
    - Auto-request now places the hidden requester at the nearest roboport (within 256 tiles) to guarantee logistic coverage.
    - Adds clear debug messages when a request can't be created or set.

Version: 1.3.7
Date: 2026-01-25
  Changes:
    - Fixed crash on Deposit/List in some Factorio 2.x builds: never reads missing LuaEntity methods directly; request APIs are called via pcall with fallbacks.

Version: 1.3.6
Date: 2026-01-25
  Changes:
    - Fixed logistic auto-request not triggering in some modpacks: requester chest now uses set_request_slot() API first, with safe fallbacks.

Version: 1.3.5
Date: 2026-01-25
  - Fix: logistic auto-request now works across Factorio runtime variants (requester point/indices/section APIs differ).

Version: 1.3.4
Date: 2026-01-25
  - Fixed logistic auto-request not triggering: corrected requester logistic point API call (get_logistic_point signature) and added safe fallbacks.

Version: 1.3.3
Date: 2026-01-25
  Changes:
    - NEW: Auto-request missing items from logistic network when creating/accepting trades (uses hidden requester near a Trade Radar).
    - Pending trades complete automatically once items arrive.

Version: 1.2.2
Date: 2026-01-24
  - Fixed Deposit/List crash in quality-enabled games: constant combinator virtual signals now set quality="normal" (required when min>0).

Version: 1.2.2
Date: 2026-01-24
  - Fixed Deposit/List crash in quality-enabled games: virtual signals written to combinator slots now include quality=normal when min>0.

Version: 1.2.1
Date: 2026-01-24
  - Fixed save load crash on Factorio 2.x: avoid direct access to game.item_prototypes (missing-key access throws); use prototypes.item or pcall fallback.

Version: 1.2.0
Date: 2026-01-24
  - Fixed load failure on Factorio 2.x: prototype access uses LuaPrototypes (prototypes.item) when game.item_prototypes is unavailable.

Version: 1.1.9
Date: 2026-01-24
  - Fixed Deposit/List crash: escrow metadata no longer writes item filters (uses virtual-signal item indices instead), avoiding item quality restrictions.

Version: 1.1.8
Date: 2026-01-24
  - Fixed deposit/list crash on quality-enabled games: escrow combinator item signals now explicitly request common quality.

Version: 1.1.7
Date: 2026-01-24
  - Fixed offer button crash: escrow combinator slots no longer include any item quality fields (defaults to common).

Version: 1.1.6
Date: 2026-01-24
  - Fixed offer listing crash on quality-enabled games: escrow combinator slots no longer force a non-common item quality.

Version: 1.1.5
Date: 2026-01-24
  - Fixed offer listing crash (Factorio 2.0 constant combinator scripting uses logistic sections).
  - UI can be closed with E/ESC and Ctrl+T toggles reliably.
Version: 1.1.4
Date: 2026-01-25
  Changes:
    - Fixed mod load error: escrow chest picture.layers can’t be empty; reverted to base chest graphics (still non-selectable and off-grid).
Version: 1.1.3
Date: 2026-01-25
  Changes:
    - Fixed mod load error: removed invalid entity prototype flag "hidden" from escrow entities.
Version: 1.1.2
Date: 2026-01-25
  Changes:
    - Compatibility fix: escrow entities now use collision_mask = {layers={}} (Factorio 2.x / collision-mask-util expectation).
      This prevents other mods from crashing when scanning prototypes (e.g. SpidertronEnhancements).
Version: 1.1.1
Date: 2026-01-25
  Changes:
    - Fixed offer persistence: each offer now uses its own unique escrow chest/combinator (no overwriting when multiple offers exist).
Version: 1.1.0
Date: 2026-01-25
  Changes:
    - Fixed offers/items being lost on reload: offers are now backed by hidden escrow entities on the map.
    - On load, offers are rebuilt by scanning escrow combinators, so offers persist even if global state is disrupted.
Version: 1.0.8
Date: 2026-01-25
  Changes:
    - Fixed offer persistence edge-case: init now rebuilds offer index (offer_ids) from saved offers so offers always reappear after reload and escrow cannot be "lost" from the UI.
Version: 1.0.7
Date: 2026-01-25
  Changes:
    - Fixed multiplayer desync further: rescan_all_radars now iterates surfaces deterministically and sorts found radars by unit_number.
Version: 1.0.6
Date: 2026-01-25
  Changes:
    - Fixed multiplayer desync: made radar scanning and multi-radar pooling deterministic (sorted by unit_number; surfaces iterated by index).
Version: 1.0.5
Date: 2026-01-25
  Changes:
    - Fixed crash on UI open: removed stray pdftt_close handler from refresh_browse().
Version: 1.0.4
Date: 2026-01-25
  Changes:
    - Fixed crash on UI open: removed accidental close-button handler inserted into refresh_browse().
Version: 1.0.3
Date: 2026-01-25
  Changes:
    - Added a UI close button (top-right).
    - Ctrl+T now toggles the Trade UI (opens if closed, closes if open).
Version: 1.0.2
Date: 2026-01-25
  Changes:
    - Added item icons in Browse offers list (offer/want).
    - Increased default trade energy cost to 10x (startup setting default).
    - Built on the stable multi-radar pooling branch.
Version: 0.0.17
Date: 2026-01-25
  Changes:
    - Fixed crash on init: rescan_all_radars is now forward-declared so on_init can call it safely.
Version: 0.0.16
Date: 2026-01-25
  Changes:
    - Fixed Ctrl+T saying "Build at least one Trade Radar first" in existing saves: the mod now rescans all surfaces for existing Trade Radars on init/config-change and on hotkey use.
Version: 0.0.15
Date: 2026-01-25
  Changes:
    - Browse list now labels clearly: "They offer" vs "They want".
    - UI no longer requires selecting a radar; items and energy are pooled across ALL Trade Radars of your force.
    - Trades now take/insert/remove items across all Send/Receive ports for each force (multi-radar support).
    - Performed full control.lua stability pass to avoid leftover fragment errors.
Version: 0.0.14
Date: 2026-01-25
  Changes:
    - Fixed crash when creating offers: GUI elements are now found recursively (no longer assuming direct-child layout).
Version: 0.0.13
Date: 2026-01-25
  Changes:
    - Fixed missing port chests: ports now spawn 2 tiles north/south of the Trade Radar to avoid collision with the radar footprint.
    - Fixed "Trade Radar not found" spam by storing per-player UI context for the opened radar.
    - Added clearer error messages when ports cannot be created due to blocked tiles.
Version: 0.0.12
Date: 2026-01-25
  Changes:
    - Full control.lua rewrite for stability.
    - UI only opens via hotkey (Ctrl+T default) with a Trade Radar selected (no auto-open).
    - Offers are global and can be accepted by any force.
    - Fixed deposits/listing by always ensuring Send/Receive ports exist and using direct inventory operations.
    - Fixed GUI close crashes and removed leftover patch fragments from earlier versions.
Version: 0.0.11
Date: 2026-01-25
  Changes:
    - Fixed crash on GUI close: added global destroy_gui() helper so on_gui_closed can safely destroy the UI.
Version: 0.0.10
Date: 2026-01-25
  Changes:
    - Fixed load crash: removed stray leftover "end / return out / end" block that caused <eof> expected near 'end'.
Version: 0.0.9
Date: 2026-01-25
  Changes:
    - Fixed Lua syntax error by removing leftover fragment of an old dropdown helper (stray 'end' near GUI section).
Version: 0.0.8
Date: 2026-01-25
  Changes:
    - Fixed remaining syntax error: removed stray "return send, recv" block left after port function refactor.
Version: 0.0.7
Date: 2026-01-25
  Changes:
    - Fixed syntax error in control.lua caused by an accidental leftover fragment during a previous patch.
Version: 0.0.6
Date: 2026-01-25
  Changes:
    - Fixed locale load error by removing duplicate [ftt-gui] section header.
Version: 0.0.5
Date: 2026-01-25
  Changes:
    - UI no longer auto-opens; use hotkey (default Ctrl+T) with a Trade Radar selected.
    - Offers are now GLOBAL: visible to all forces; any force can accept (no target force selection).
    - Fixed deposit/list issues by ensuring Send/Receive ports exist for each Trade Radar and improving escrow refunds.
Version: 0.0.4
Date: 2026-01-25
  Changes:
    - Fixed crash on load in Factorio 2.0 by removing registration of a non-existent event (on_player_used_entity).
    - Added selection-based UI opening (on_selected_entity_changed) so left-clicking the Trade Radar opens the trade UI.
Version: 0.0.3
Date: 2026-01-25
  Changes:
    - Made Send/Receive ports selectable and operable so players can insert/remove items manually.
    - Added fallback interaction handler (on_player_used_entity) so opening the radar is more reliable.
Version: 0.0.2
Date: 2026-01-25
  Changes:
    - Fixed crash on init by ensuring global table exists before indexing.
Version: 0.0.1
Date: 2026-01-25
  Changes:
    - Experimental release (0.0.1).
    - Force-to-force trading via Trade Radar UI (offers, accept, cancel).
    - Trade consumes configurable energy per trade (startup setting).