From 2f4a2385f1f7516c7588e76e7059d6ba91484e8d Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 8 Aug 2026 18:57:45 -0700 Subject: [PATCH 1/2] Open 0.2.1, and make the feedstock as illegal as the good Version to 0.2.1-SNAPSHOT: 0.2.0 is out, and the next thing to land will be a fix. First of those: sugar cane is contraband now. One cane crafts into one sugar, so a hold full of cane walked through a customs scan clean and became contraband on the far side with a single click - the whole crime layer was theatre for anyone who had read a recipe book (Ben, playtest). SUGAR_CANE joins SUGAR in illegal-trade.contraband-materials, in the code default AND in config.yml: a list in config REPLACES the default rather than merging, so shipping one without the other fixes nothing on a server that already has a config. Knock-on effects, all intended - farm ports no longer stock cane over the counter (saleCatalog filters contraband), customs scans catch it in hold and pockets, and the black-market premium applies to it. The rule for when the list grows next, now in the config comment: list the FEEDSTOCK as well as the finished good. 611 tests green. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014as2obVi1QJj8CRTSqXBRr --- pom.xml | 2 +- .../java/world/bentobox/tradewinds/Settings.java | 5 ++++- src/main/resources/config.yml | 4 ++++ .../bentobox/tradewinds/crime/ContrabandTest.java | 12 ++++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 99f0609..8e25fed 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ -LOCAL - 0.2.0 + 0.2.1 diff --git a/src/main/java/world/bentobox/tradewinds/Settings.java b/src/main/java/world/bentobox/tradewinds/Settings.java index a45d675..9ac8876 100644 --- a/src/main/java/world/bentobox/tradewinds/Settings.java +++ b/src/main/java/world/bentobox/tradewinds/Settings.java @@ -742,8 +742,11 @@ private static Map defaultBoatRanks() { @ConfigComment("The contraband list: what customs care about, and what black markets pay") @ConfigComment("the premium for. Only honored while illegal-trade.enabled is true.") + @ConfigComment("List the FEEDSTOCK as well as the finished good, or the law is theatre:") + @ConfigComment("one sugar cane crafts into one sugar, so cane smuggled past a scan is") + @ConfigComment("sugar smuggled past a scan (playtest 2026-08-09).") @ConfigEntry(path = "illegal-trade.contraband-materials") - private List contrabandMaterials = new ArrayList<>(List.of("SUGAR")); + private List contrabandMaterials = new ArrayList<>(List.of("SUGAR", "SUGAR_CANE")); @ConfigComment("Career restarts a destitute player may use (/tw restart): fresh kit, starting") @ConfigComment("balance, chart kept. -1 = unlimited, 0 = none.") diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4c17a6a..2a8454c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -752,8 +752,12 @@ encounters: illegal-trade: # The contraband list: what customs care about, and what black markets pay # the premium for. Only honored while illegal-trade.enabled is true. + # List the FEEDSTOCK as well as the finished good, or the law is theatre: + # one sugar cane crafts into one sugar, so cane smuggled past a scan is + # sugar smuggled past a scan (playtest 2026-08-09). contraband-materials: - SUGAR + - SUGAR_CANE # Master gate for all illegal-goods mechanics: contraband, customs scans, smuggling. # Set false for family-friendly servers - removes the entire crime layer cleanly. enabled: true diff --git a/src/test/java/world/bentobox/tradewinds/crime/ContrabandTest.java b/src/test/java/world/bentobox/tradewinds/crime/ContrabandTest.java index e718a1e..6143621 100644 --- a/src/test/java/world/bentobox/tradewinds/crime/ContrabandTest.java +++ b/src/test/java/world/bentobox/tradewinds/crime/ContrabandTest.java @@ -30,6 +30,18 @@ void testMasterGateRemovesTheWholeMechanic() { assertFalse(Contraband.isContraband("BREAD", LIST, true)); } + @Test + void testTheFeedstockIsAsIllegalAsTheGood() { + // One cane crafts into one sugar, so cane past a scan is sugar past a + // scan - and the shipped default has to say so, or the whole customs + // layer is theatre for anyone who reads a recipe book (2026-08-09). + // Both lists, because a map/list in config.yml REPLACES the code + // default rather than merging with it. + var shipped = new world.bentobox.tradewinds.Settings().getContrabandMaterials(); + assertTrue(shipped.contains("SUGAR"), "SUGAR must be contraband by default"); + assertTrue(shipped.contains("SUGAR_CANE"), "SUGAR_CANE must be contraband by default"); + } + @Test void testSafePortsRefuseContraband() { // Crime pays, into danger: the safe ports will not touch it, so a From 849827b0c54559963320ff3df6d541bc664d2dd4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 8 Aug 2026 19:01:18 -0700 Subject: [PATCH 2/2] Delete the customs stamp, which left three years of comments behind Custom stamping is gone (it went with the hold plan on 2026-08-01) but its paperwork stayed: economy.unstamped-sellables sat in config.yml listing SUGAR, with no @ConfigEntry behind it and nothing in the codebase reading it - a knob that promised "traders buy this even WITHOUT a customs stamp" and did nothing at all. Deleted, with the locale item.stamp ("Customs Stamped") that nothing renders any more. The comments that outlived the feature go too: Contraband's javadoc still described stamping as the boundary of what may be sold, the booty settings claimed drops were "customs-stamped, so salvage can be sold", the buying page told players their goods were stamped, and CustomsService.sellableAt called the band rule an addition "on top of the customs stamp" when it is now the only thing that refuses a sale. 611 tests green. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014as2obVi1QJj8CRTSqXBRr --- .../java/world/bentobox/tradewinds/Settings.java | 4 ++-- .../world/bentobox/tradewinds/crime/Contraband.java | 12 +++++++----- .../bentobox/tradewinds/crime/CustomsService.java | 5 +++-- src/main/resources/config.yml | 5 +---- src/main/resources/locales/en-US.yml | 3 +-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/world/bentobox/tradewinds/Settings.java b/src/main/java/world/bentobox/tradewinds/Settings.java index 9ac8876..3a8aaed 100644 --- a/src/main/java/world/bentobox/tradewinds/Settings.java +++ b/src/main/java/world/bentobox/tradewinds/Settings.java @@ -1138,8 +1138,8 @@ private static Map defaultEncounterChance() { @ConfigEntry(path = "encounters.booty-chance") private double bootyChance = 0.5; - @ConfigComment("Booty materials. Dropped customs-stamped, so salvage can be sold -") - @ConfigComment("fighting is the third way to earn, beside trading and smuggling.") + @ConfigComment("Booty materials. Sellable like any other cargo, so fighting is the third") + @ConfigComment("way to earn, beside trading and smuggling.") @ConfigEntry(path = "encounters.booty-table") private List bootyTable = new ArrayList<>(List.of("NAUTILUS_SHELL", "PRISMARINE_SHARD", "PRISMARINE_CRYSTALS", "GOLD_INGOT", "IRON_INGOT", "EMERALD", "COAL", "COOKED_COD", "TRIDENT", diff --git a/src/main/java/world/bentobox/tradewinds/crime/Contraband.java b/src/main/java/world/bentobox/tradewinds/crime/Contraband.java index a18588c..a45cb3d 100644 --- a/src/main/java/world/bentobox/tradewinds/crime/Contraband.java +++ b/src/main/java/world/bentobox/tradewinds/crime/Contraband.java @@ -7,11 +7,13 @@ /** * What customs would rather you were not carrying. *

- * Contraband is the one thing a player can make and still sell (spec - * 5.0): everything else traders buy must carry a customs stamp, so money only - * ever enters the game through trade margins. Contraband is the deliberate - * hole in that rule, and scan risk is what it is priced against - crime pays, - * into danger (principle 4). + * Contraband is what a port's law cares about, and what a black market pays + * the premium for. Scan risk is what that premium is priced against - crime + * pays, into danger (principle 4). + *

+ * It no longer marks the boundary of what may be sold: customs STAMPING was + * removed with the hold plan (2026-08-01), and the market now buys anything + * with a price. What survived is the smuggling risk. *

* Pure logic, no Bukkit: which bands deal in it, and how likely a search is. * The material list itself lives in config. diff --git a/src/main/java/world/bentobox/tradewinds/crime/CustomsService.java b/src/main/java/world/bentobox/tradewinds/crime/CustomsService.java index 7014b64..753a4f8 100644 --- a/src/main/java/world/bentobox/tradewinds/crime/CustomsService.java +++ b/src/main/java/world/bentobox/tradewinds/crime/CustomsService.java @@ -495,8 +495,9 @@ public boolean buysContraband(SecurityBand band) { } /** - * Whether an item may be sold at this island - the contraband rule on top - * of the customs stamp. + * Whether an item may be sold at this island. Since customs stamping went + * (hold plan, 2026-08-01) the contraband band rule is the ONLY thing that + * refuses a sale: anything else with a price, a port will take. * * @param spec the island * @param item the item diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2a8454c..631be3e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -344,9 +344,6 @@ economy: # The harbourmaster's charity: a sailor with no cargo space, no boat and no money # is given the bare minimum to work again. Charity goods cannot be sold. 0 disables. charity-cooldown-minutes: 15 - # Materials traders buy even WITHOUT a customs stamp - the contraband exceptions. - unstamped-sellables: - - SUGAR # The secondhand shelf: notable goods sold to a trader go back out for sale # instead of vanishing, so the world feels inhabited. They surface at a DIFFERENT # port from the one they were sold at (the trader shipped it on), which stops @@ -733,7 +730,7 @@ encounters: PIRATE_CREW: 10 SEA_WITCH: 30 # Chance that a slain encounter mob yields booty, and what it may drop. - # Booty is customs-stamped, so it can be sold: fighting is the third way to earn. + # Booty is sellable like any other cargo: fighting is the third way to earn. booty-chance: 0.5 booty-table: - NAUTILUS_SHELL diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index afc5923..68f5a2a 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -279,7 +279,7 @@ tradewinds: selling-body: "The island pays for goods in your hold" selling-truncated: "(showing the first [number] cargo types - sell some to see the rest)" buying-title: "[name] - Buying" - buying-body: "Goods sold into your hold - customs stamped" + buying-body: "Goods sold into your hold - buy low, sell high elsewhere" outfitter-title: "[name] - Outfitter" outfitter-body: "Stores for the sailing life - food, fuel and gear" shipwright-title: "[name] - Shipwright" @@ -334,7 +334,6 @@ tradewinds: pouch-lore: "Cargo space. Stow goods to sell them." expander: "Cargo Expander" expander-lore: "Expands your hold. Right-click to open." - stamp: "Customs Stamped" starchart: "Star Chart" ships-compass: "Ship's Compass" ships-compass-lore: "Points to your island, from anywhere. Guard it - or gift it to a crewmate."