The Farmer Was Replaced Achievement Guide
This guide is a collection of how to complete the most difficult challenges in The Farmer Was Replaced, a game where you use drone(s) to automate farming a progressively more complicated series of crops using a subset of the Python language.
In my job I very rarely get a chance to write code completely by hand anymore, and knew very little about Python itself, so I took 100%ing the game as a chance to reinvigorate my love of code while learning a new language at the same time. To that end, the entirety of the code on this page is completely hand written, no LLMs allowed here.
The guide is divided into logical groupings based on the required crop for each achievement, and for the most part a single script is sufficient to get them all at the same time. Most code shares a few functions, and so a Common library exists at the bottom of this page.
Achievements
Sunflower Master & Big Power Farmer


These are worth figuring out first, because you'll want a stash of excess Power in order to move fast enough to do anything below. This really simply assigns each drone a column of your farm, plants Sunflowers, and then scans the column over and over again for anything to harvest.
This pays no heed to the internal game rules to maximize production and still yields about 14,000 Power per minute. Plenty for our purposes.
# Power.py
import Common
entity = Entities.Grass
instructions = Common.get_planting_instructions(entity)
def driver(x, y):
Common.move_to(x,y)
instructions()
while True:
while get_water() < 0.75:
use_item(Items.Water)
Common.polyculture()
Common.await_harvest()
harvest()
clear()
for i in range(6):
for j in range(6):
if i + j != 0:
spawn_drone(driver, 3 + i*5, 3 + j*5)
driver(3, 3)
Hay Master & Big Hay Farmer


The Hay related achievements can be tackled by making efficient use of Polyculture and keeping your Water levels high enough.
The algorithm is fairly simple for this one and really only is harvesting a single plot. Space each of your drones out into a grid with 5 spaces between them. Then, you can simply call get_companion() on the drone to grab the Polyculture requirements, plant that and then just come back to your plot. Each adjacent drone will technically share a single space and occasionally collide, but this is a very rare race condition not worth optimizing.
# Hay.py
import Common
entity = Entities.Sunflower
instructions = Common.get_planting_instructions(entity)
def driver(x,y):
Common.move_to(x,y)
while True:
while get_water() < 0.75:
use_item(Items.Water)
if can_harvest():
harvest()
instructions()
move(North)
clear()
for x in range(1, 32):
spawn_drone(driver, x, 0)
driver(0, 0)
Following this correctly should yield around 550,000,000 Hay per minute.
Wood Master & Big Wood Farmer


This is where things get a bit more difficult. The Hay algorithm using a single plot is insufficient here because it will get bottlenecked on the much longer time Trees take to grow.
Instead, we play a trick with the Polyculture system where we re-plant over and over again until we get a desirable outcome. Assign each drone a column, and plant Trees in a checkerboard pattern, leaving Hay wherever Trees are not placed. When planting a new tree, immediately call get_companion() on it. If the resulting pairing is not Hay or if the distance from the origin tile is equal to 2 (per the checkerboard pattern), retry.
# Trees.py
import Common
entity = Entities.Tree
instructions = Common.get_planting_instructions(entity)
def driver(x,y):
Common.move_to(x,y)
while True:
Common.await_harvest()
while get_water() < 0.5:
use_item(Items.Water)
harvest()
instructions()
loop = False
while loop == False:
harvest()
plant(entity)
plant_type, (px, py) = get_companion()
if plant_type == Entities.Grass:
if abs(x - px) + abs(y - py) != 2:
loop = True
move(North)
move(North)
clear()
for x in range(1, get_world_size()):
spawn_drone(driver, x, x % 2)
driver(0, 0)Carrot Master & Big Carrot Farmer


Carrots share the exact same problem space as Tree farming, so we can just copy that solution and apply it here, too.
# Carrot.py
import Common
entity = Entities.Carrot
instructions = Common.get_planting_instructions(entity)
def driver(x,y):
Common.move_to(x,y)
while True:
Common.await_harvest()
while get_water() < 0.5:
use_item(Items.Water)
harvest()
instructions()
loop = False
while loop == False:
harvest()
plant(entity)
plant_type, (px, py) = get_companion()
if plant_type == Entities.Grass:
if abs(x - px) + abs(y - py) != 2:
loop = True
move(North)
move(North)
clear()
for x in range(1, get_world_size()):
spawn_drone(driver, x, x % 2)
driver(0, 0)Cactus Master & Big Cactus Farmer



Cactus require using drones to sort each column and row in parallel with each other. The one real snag is that if a drone starts sorting a column while another is still sorting a row their efforts will conflict with each other. To further complicate this, drones have no channel to communicate with each other directly, they can only check if other drones exist.
The solution to this is to maintain a 'master' drone that delegates its' tasks to slave drones, and use the death of a drone when its' task finishes to signal that a row or column has finished. So the process from your master drone becomes:
- Assign drones to sort rows
- Wait for them to finish
- Assign drones to sort columns wait again
- Call
harvest()and repeat
For Wrong Order, simply use sort_desc instead of sort_asc in the Cactus code below.
# Cactus.py
import Common
def sort(stack, comparator):
for index in range(len(stack)):
lowest_index = index
for c in range(index + 1, len(stack)):
if comparator(stack[c], stack[lowest_index]):
lowest_index = c
tmp = stack[index]
stack[index] = stack[lowest_index]
stack[lowest_index] = tmp
return stack
def sort_asc(stack):
def comparator(a, b):
return a < b
return sort(stack, comparator)
def sort_desc(stack):
def comparator(a, b):
return a > b
return sort(stack, comparator)
def prep_field(entity, dir, instructions):
sizes = []
for i in range(get_world_size()):
instructions()
plant(entity)
sizes.append(measure())
move(dir)
return sizes
def move_item(x, y):
while get_pos_x() < x:
swap(East)
move(East)
while get_pos_x() > x:
swap(West)
move(West)
while get_pos_y() < y:
swap(North)
move(North)
while get_pos_y() > y:
swap(South)
move(South)
def perform_sort(array, dir):
for i in range(len(array)):
target_number = array[i]
m = measure()
while m != target_number:
move(dir)
m = measure()
if dir == North or dir == South:
x = get_pos_x()
move_item(x, i)
if i + 1 < get_world_size():
Common.move_to(x, i + 1)
else:
y = get_pos_y()
move_item(i, y)
if i + 1 < get_world_size():
Common.move_to(i + 1, y)
# Cactus Driver.py
import Common
import Cactus
entity = Entities.Cactus
def driver(x, y, dir):
Common.move_to(x,y)
# Delegate spawning additional drones recursively
if num_drones() < max_drones():
if dir == North or dir == South:
spawn_drone(driver, x + 1, 0, dir)
else:
spawn_drone(driver, 0, y + 1, dir)
instructions = Common.get_planting_instructions(entity)
sizes = Cactus.prep_field(entity, dir, instructions)
sorted = Cactus.sort_asc(sizes)
Cactus.perform_sort(sorted, dir)
clear()
# Drone 0 acts as the control plane
# It delegates jobs to short lived slave drones
while True:
driver(0, 0, East)
count = num_drones()
while count > 1:
count = num_drones()
driver(0, 0, North)
count = num_drones()
while count > 1:
count = num_drones()
harvest()
Common.move_to(0,0)Pumpkin Master & Big Pumpkin Farmer


Pumpkin Master requires parallelizing the farming of one giant farm-sized pumpkin while managing Fertilizer usage. Assign each drone a column and set them up to make 2 passes over the field. On the first pass the drone simply plants a Pumpkin in each row. On the second pass, find any failed crops and re-plant them while using Fertilizer to speed up growth.
The above strategy is fairly straight forward, the only problem is - how do you know when to call harvest()? Pumpkins fortunately have an undocumented property we can take advantage of: they assign themselves a unique integer that you can discover with measure(). Pumpkins that merge together also take on the identity of the oldest surviving Pumpkin. So if each drone stores the identifier of the first Pumpkin it plants they can check what the identifier of the Pumpkin underneath them is after they have finished both passes. If the identifier matches their first plant you can assume the Pumpkin has finished propagating, then call harvest() and start over again.
# Pumpkins.py
import Common
entity = Entities.Pumpkin
instructions = Common.get_planting_instructions(entity)
def force_grow_pumpkin():
gee = get_entity_type()
if gee == None:
return True
if gee == Entities.Pumpkin and can_harvest():
return True
plant(Entities.Pumpkin)
use_item(Items.Fertilizer)
use_item(Items.Weird_Substance)
use_item(Items.Weird_Substance)
return force_grow_pumpkin()
def driver(x, y):
Common.move_to(x,y)
if x != get_world_size() - 1:
spawn_drone(driver, x + 1, 0)
while True:
protocol(x, y)
def protocol(x,y):
first_pumpkin = -1
# First pass - plant normally
for i in range(get_world_size()):
instructions()
if i == 0:
first_pumpkin = measure()
while get_water() < 0.75:
use_item(Items.Water)
move(North)
# Second pass, replant and Fertilizer
for i in range(get_world_size()):
force_grow_pumpkin()
if i == 0:
first_pumpkin = measure()
# Once finished, check to see if
# our drone's first pumpkin is the winner
if get_pos_y() == get_world_size() - 1:
m = measure()
while m != None:
m = measure()
if m == first_pumpkin:
harvest()
move(North)
clear()
driver(0, 0)Maze Master, Recycling, & Big Gold Farmer



Achieving 2 million Gold in 1 minute is the second hardest achievement behind getting on the Full Reset leaderboard, and required at least 4-5 completely different attempts to get right.
In the end, the approach was to segment the farm off into 16 chunks and send two drones into each chunk, allowing the drones. The drones then explore the maze until they find the treasure. Drones keep track of where they've gone using a recursive algorithm that forks off on every intersection in the maze, so when a drone needs to come back from a dead end it can simply pop its' backstack of directions until it arrives at its' last intersection. Drones also maintain a memory of dead ends it hits, so once walls start being removed the drone does not get caught in an infinite loop.
Segmentation into multiple mazes instead of one large maze was chosen to increase the efficiency gained by wall removal when a maze is re-used. 16 mazes can have many more walls removed before needing to be reset than 1 large maze.
Drones also order the paths they explore by the distance their next move is from the Treasure. The first drone will always move in the direction that takes it closer to the Treasure, and does most of the heavy lifting for maze resolution. The second drone takes the opposite approach and explores the least likely so they do not gradually converge on each other and stay overlapping forever.
Finally, before any of the above happens, the Drone has to call measure() to check if the other drone solved the maze. If it has, reset and repeat.
# Mazes.py
import Common
opposite_directions = {
North: South,
South: North,
East: West,
West: East
}
coordinate_adjustments = {
North: [0, 1],
South: [0, -1],
East: [1, 0],
West: [-1, 0]
}
is_slave = False
dead_ends = []
treasure_location = None
def reset_memory():
global dead_ends
dead_ends = []
global treasure_location
treasure_location = measure()
def harvest_treasure(maze_size):
substance = maze_size * 2**(num_unlocked(Unlocks.Mazes) - 1)
success = use_item(Items.Weird_Substance, substance)
def initialize_maze(maze_size, x, y):
harvest()
Common.move_to(x,y)
plant(Entities.Bush)
harvest_treasure(maze_size)
def random_elem(list):
index = random() * len(list) // 1
return list[index]
def valid_moves(previous_move = None):
ret = []
moves = set((North, East, South, West))
if get_entity_type() == Entities.Grass:
return ret
if previous_move != None:
moves.remove(opposite_directions[previous_move])
for m in set(moves):
adj = coordinate_adjustments[m]
px, py = get_pos_x(), get_pos_y()
x, y = px + adj[0], py + adj[1]
if not can_move(m) or is_dead_end(x, y):
moves.remove(m)
else:
meas = measure()
if meas == None:
return []
tx, ty = meas[0], meas[1]
distx = abs(tx - px)
disty = abs(ty - py)
cdistx = abs(tx - x)
cdisty = abs(ty - y)
if cdistx + cdisty < distx + disty:
ret.insert(0, m)
else:
ret.append(m)
# slave works backwards
if is_slave:
rev = []
for i in range(len(ret)):
rev.insert(0, ret.pop())
return rev
return ret
def is_dead_end(x = get_pos_x(), y = get_pos_y()):
for i in dead_ends:
if i[0] == x and i[1] == y:
return True
return False
def backtrack(backstack):
while(len(backstack) > 0):
if get_entity_type() == Entities.Treasure:
global dead_ends
dead_ends = []
return True
move(backstack.pop())
return False
def recurse(direction, backstack):
move(direction)
backstack.append(opposite_directions[direction])
meas = measure()
if meas != treasure_location:
reset_memory()
return False
entity = get_entity_type()
if entity != Entities.Hedge and entity != Entities.Treasure:
return False
if entity == Entities.Treasure:
return True
moves = valid_moves(direction)
move_len = len(moves)
if move_len > 1:
global dead_ends
dead_ends.append([get_pos_x(), get_pos_y()])
for m in moves:
if m == opposite_directions[direction]:
continue
ret = recurse(m, [])
if ret == True:
return True
bt = backtrack(backstack)
backstack = []
return bt
def start_solving(set_slave = False):
global is_slave
is_slave = set_slave
reset_memory()
moves = valid_moves()
for m in moves:
ret = recurse(m, [])
if ret:
return TrueDino Master, Long Dinosaur, Size Matters, & Big Bone Farmer




Despite being at the bottom of the list, this is one of the easiest solutions to put together by using something called a Hamiltonian Cycle. Simply put, you find a path that both travels every plot on the farm exactly once that also ends where it begins, and just follow it over and over again until the Snake spans the entire farm. This is a fairly slow process, but once it completes all of the achievements above should unlock at once.
# Dinosaurs.py
def movef(dir):
if not can_move(dir):
return True
move(dir)
return False
def cycle():
ws = get_world_size()
change_hat(Hats.Brown_Hat)
change_hat(Hats.Dinosaur_Hat)
while True:
# Loop north
while get_pos_y() < ws - 1:
if movef(North):
return True
if get_pos_x() != ws - 1:
if movef(East):
return True
# Loop south to y = 1
while get_pos_y() > 1:
if movef(South):
return True
if get_pos_x() != ws - 1:
if movef(East):
return True
# If we're at the end, go down
# then travel west back to the start
if(get_pos_x() == ws - 1 and get_pos_y() == 1):
if movef(South):
return True
while get_pos_x() != 0:
if movef(West):# Dino_Achievement.py
import Dinosaurs
clear()
while(True):
Dinosaurs.cycle()Full Automation

This is the most challenging of all achievements in the game, deserving of its' own post. Coming soon.
Common Code
Some code is shared amongst most or all the achievement scripts. They are detailed here for reference.
# Common.py
def await_harvest():
h = can_harvest()
while not h:
h = can_harvest()
def move_to(x, y):
# For full reset - can_move() is unlocked when Mazes are
def p_can(dir):
return num_unlocked(Unlocks.Mazes) == 0 or can_move(dir)
while get_pos_x() < x and p_can(East):
move(East)
while get_pos_x() > x and p_can(West):
move(West)
while get_pos_y() < y and p_can(North):
move(North)
while get_pos_y() > y and p_can(South):
move(South)
def p_make_callback(entity, ground_type):
def callback():
if get_ground_type() != ground_type:
till()
if get_entity_type() != entity:
plant(entity)
return callback
p_planting_table = {
Entities.Grass: p_make_callback(Entities.Grass, Grounds.Grassland),
Entities.Bush: p_make_callback(Entities.Bush, Grounds.Grassland),
Entities.Carrot: p_make_callback(Entities.Carrot, Grounds.Soil),
Entities.Tree: p_make_callback(Entities.Grass, Grounds.Grassland),
Entities.Cactus: p_make_callback(Entities.Cactus, Grounds.Soil),
Entities.Pumpkin: p_make_callback(Entities.Pumpkin, Grounds.Soil),
Entities.Sunflower: p_make_callback(Entities.Sunflower, Grounds.Soil),
}
def get_planting_instructions(entity):
return p_planting_table[entity]
def polyculture():
x, y = get_pos_x(), get_pos_y()
plant_type, (px, py) = get_companion()
instructions = get_planting_instructions(plant_type)
move_to(px, py)
harvest()
instructions()
move_to(x, y)