--- a/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
+++ b/net/minecraft/world/entity/npc/WanderingTraderSpawner.java
@@ -30,16 +_,14 @@
     private static final int SPAWN_CHANCE_INCREASE = 25;
     private static final int SPAWN_ONE_IN_X_CHANCE = 10;
     private static final int NUMBER_OF_SPAWN_ATTEMPTS = 10;
-    private final RandomSource random = RandomSource.create();
+    private final RandomSource random = io.papermc.paper.threadedregions.util.ThreadLocalRandomSource.INSTANCE; // Folia - region threading
     private final ServerLevelData serverLevelData;
-    private int tickDelay;
-    private int spawnDelay;
-    private int spawnChance;
+    // Folia - region threading
 
     public WanderingTraderSpawner(ServerLevelData serverLevelData) {
         this.serverLevelData = serverLevelData;
         // Paper start - Add Wandering Trader spawn rate config options
-        this.tickDelay = Integer.MIN_VALUE;
+        //this.tickDelay = Integer.MIN_VALUE; // Folia - region threading - moved to regionisedworlddata
         // this.spawnDelay = serverLevelData.getWanderingTraderSpawnDelay();
         // this.spawnChance = serverLevelData.getWanderingTraderSpawnChance();
         // if (this.spawnDelay == 0 && this.spawnChance == 0) {
@@ -53,35 +_,36 @@
 
     @Override
     public int tick(ServerLevel level, boolean spawnHostiles, boolean spawnPassives) {
+        io.papermc.paper.threadedregions.RegionizedWorldData worldData = level.getCurrentWorldData(); // Folia - region threading
         // Paper start - Add Wandering Trader spawn rate config options
-        if (this.tickDelay == Integer.MIN_VALUE) {
-            this.tickDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
-            this.spawnDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnDayLength;
-            this.spawnChance = level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin;
+        if (worldData.wanderingTraderTickDelay == Integer.MIN_VALUE) { // Folia - region threading
+            worldData.wanderingTraderTickDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading
+            worldData.wanderingTraderSpawnDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Folia - region threading
+            worldData.wanderingTraderSpawnChance = level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Folia - region threading
         }
         if (!level.getGameRules().getBoolean(GameRules.RULE_DO_TRADER_SPAWNING)) {
             return 0;
-        } else if (--this.tickDelay - 1 > 0) {
-            this.tickDelay = this.tickDelay - 1;
+        } else if (--worldData.wanderingTraderTickDelay - 1 > 0) { // Folia - region threading
+            worldData.wanderingTraderTickDelay = worldData.wanderingTraderTickDelay - 1; // Folia - region threading
             return 0;
         } else {
-            this.tickDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
-            this.spawnDelay = this.spawnDelay - level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength;
+            worldData.wanderingTraderTickDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading
+            worldData.wanderingTraderSpawnDelay = worldData.wanderingTraderSpawnDelay - level.paperConfig().entities.spawning.wanderingTrader.spawnMinuteLength; // Folia - region threading
             //this.serverLevelData.setWanderingTraderSpawnDelay(this.spawnDelay); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
-            if (this.spawnDelay > 0) {
+            if (worldData.wanderingTraderSpawnDelay > 0) { // Folia - region threading
                 return 0;
             } else {
-                this.spawnDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnDayLength;
+                worldData.wanderingTraderSpawnDelay = level.paperConfig().entities.spawning.wanderingTrader.spawnDayLength; // Folia - region threading
                 if (!level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
                     return 0;
                 } else {
-                    int i = this.spawnChance;
-                    this.spawnChance = Mth.clamp(this.spawnChance + level.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax);
+                    int i = worldData.wanderingTraderSpawnChance; // Folia - region threading
+                    worldData.wanderingTraderSpawnChance = Mth.clamp(worldData.wanderingTraderSpawnChance + level.paperConfig().entities.spawning.wanderingTrader.spawnChanceFailureIncrement, level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin, level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMax); // Folia - region threading
                     //this.serverLevelData.setWanderingTraderSpawnChance(this.spawnChance); // Paper - We don't need to save this value to disk if it gets set back to a hardcoded value anyways
                     if (this.random.nextInt(100) > i) {
                         return 0;
                     } else if (this.spawn(level)) {
-                        this.spawnChance = level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin;
+                        worldData.wanderingTraderSpawnChance = level.paperConfig().entities.spawning.wanderingTrader.spawnChanceMin; // Folia - region threading
                         // Paper end - Add Wandering Trader spawn rate config options
                         return 1;
                     } else {
@@ -93,7 +_,7 @@
     }
 
     private boolean spawn(ServerLevel serverLevel) {
-        Player randomPlayer = serverLevel.getRandomPlayer();
+        Player randomPlayer = serverLevel.getRandomLocalPlayer(); // Folia - region threading
         if (randomPlayer == null) {
             return true;
         } else if (this.random.nextInt(10) != 0) {
@@ -116,7 +_,7 @@
                         this.tryToSpawnLlamaFor(serverLevel, wanderingTrader, 4);
                     }
 
-                    this.serverLevelData.setWanderingTraderId(wanderingTrader.getUUID());
+                    //this.serverLevelData.setWanderingTraderId(wanderingTrader.getUUID()); // Folia - region threading - doesn't appear to be used anywhere, so avoid the race condition here...
                     // wanderingTrader.setDespawnDelay(48000); // Paper - moved above, modifiable by plugins on CreatureSpawnEvent
                     wanderingTrader.setWanderTarget(blockPos1);
                     wanderingTrader.restrictTo(blockPos1, 16);
