diff --git a/code/__defines/_protect.dm b/code/__defines/_protect.dm
index dbe25203c0..2f56cca323 100644
--- a/code/__defines/_protect.dm
+++ b/code/__defines/_protect.dm
@@ -1,6 +1,7 @@
///Protects a datum from being VV'd
#define GENERAL_PROTECT_DATUM(Path)\
##Path/can_vv_get(var_name){\
+ .=..();\
return FALSE;\
}\
##Path/vv_edit_var(var_name, var_value){\
diff --git a/code/_helpers/roundstats.dm b/code/_helpers/roundstats.dm
index 8b91b575d5..9db69b9658 100644
--- a/code/_helpers/roundstats.dm
+++ b/code/_helpers/roundstats.dm
@@ -98,6 +98,19 @@ GLOBAL_LIST_EMPTY(refined_chems_sold)
end_dols = FLOOR(end_dols * 100,1) / 100 // Truncate decimals
valid_stats_list.Add("For a total of: [points] points, or [end_dols] [end_dols > 1 ? "thalers" : "thaler"]!")
+ if(SSnerdle)
+ var/word_export = "This shift's nerdle Was: [SSnerdle.target_word]!
"
+ word_export += "There were [SSnerdle.total_players] players this shift!
"
+ var/list/splashes = list("We know what you are!", "That's how we do!", "Basically free!", "Hear them roar!", "The streak is alive!","Don't fall for them tricks!")
+ for(var/i in 1 to SSnerdle.player_attempts.len)
+ if(SSnerdle.player_attempts[i] > 0)
+ if(i < 7)
+ word_export += "There were [SSnerdle.player_attempts[i]] people who got it in [i]! [splashes[i]]
"
+ else
+ word_export += "And there were [SSnerdle.player_attempts[i]] losers who couldn't quite get it. You'll get em next time!
"
+
+ valid_stats_list.Add(word_export)
+
if(LAZYLEN(valid_stats_list))
to_chat(world, span_world("Shift trivia!"))
diff --git a/code/controllers/subsystems/nerdle.dm b/code/controllers/subsystems/nerdle.dm
new file mode 100644
index 0000000000..82380adad4
--- /dev/null
+++ b/code/controllers/subsystems/nerdle.dm
@@ -0,0 +1,29 @@
+//KEEP THE STREAK ALIVE
+SUBSYSTEM_DEF(nerdle)
+ name = "nerdle"
+ priority = FIRE_PRIORITY_APPRECIATE
+ runlevels = RUNLEVEL_GAME
+ flags = SS_BACKGROUND | SS_NO_FIRE
+ var/target_word = "fuckd"
+
+ var/list/player_attempts = list(0,0,0,0,0,0,0)//serialized, index = count of people who win/lose with that many guesses, 7 is for all the losers
+ var/total_players = 0
+
+/datum/controller/subsystem/nerdle/Initialize()
+ var/list/l = world.file2list("strings/nerdle_dict.txt")
+ target_word = pick(l)
+ l = null
+ return SS_INIT_SUCCESS
+
+/datum/controller/subsystem/nerdle/proc/report_winner_or_loser(var/guesses, var/failure = FALSE)
+ guesses = clamp(guesses,1,7)
+ if(failure)
+ guesses = 7 //fail
+
+ player_attempts[guesses] = player_attempts[guesses]+1
+ total_players ++
+
+/datum/controller/subsystem/nerdle/can_vv_get(var_name) //the sancity of nerdle shall not be infringed by man or any of the gods above them.
+ if(var_name == NAMEOF(src, target_word))
+ return FALSE
+ return ..()
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index e1b99ccfa1..aec1279029 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -2,6 +2,7 @@
return TRUE
/datum/proc/can_vv_get(var_name)
+ SHOULD_CALL_PARENT(TRUE)
if(var_name == NAMEOF(src, vars))
return FALSE
return TRUE
diff --git a/code/datums/managed_browsers/feedback_form.dm b/code/datums/managed_browsers/feedback_form.dm
index f04d162b0a..a314e6480a 100644
--- a/code/datums/managed_browsers/feedback_form.dm
+++ b/code/datums/managed_browsers/feedback_form.dm
@@ -1,8 +1,10 @@
/client
var/datum/managed_browser/feedback_form/feedback_form = null
-/client/can_vv_get(var_name)
- return var_name != NAMEOF(src, feedback_form) // No snooping.
+/client/can_vv_get(var_name)//no snooping but doesn't break shit
+ if(var_name == NAMEOF(src, feedback_form))
+ return FALSE
+ return ..()
GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index 66557f0a68..bef8826a05 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -389,7 +389,7 @@
/mob/living/carbon/human/can_fall()
if(..())
- return species.can_fall(src)
+ return species?.can_fall(src)
// Another check that we probably can just merge into can_fall exept for messing up overrides
/atom/movable/proc/can_fall_to(turf/landing)
diff --git a/code/modules/pda/nerdle.dm b/code/modules/pda/nerdle.dm
new file mode 100644
index 0000000000..2cf975bb10
--- /dev/null
+++ b/code/modules/pda/nerdle.dm
@@ -0,0 +1,114 @@
+#define NERDLE_NO 0
+#define NERDLE_YES 1
+#define NERDLE_CLOSE 2
+
+/datum/data/pda/app/nerdle
+ name = "Nerdle"
+ icon = "child-reaching" //yipee!
+ notify_icon = "child-combatant"
+ title = "Nerdle™️ V0.8"
+ template = "pda_nerdle"
+
+ var/target_word
+ var/list/guesses = list() //raw text input for guesses
+
+ var/list/serialized_guesses = list() //shortcut for tgui serialization
+
+ var/max_guesses = 6
+
+ var/completed = FALSE
+ var/failure = FALSE
+
+
+/datum/data/pda/app/nerdle/start()
+ . = ..()
+ target_word = SSnerdle.target_word
+
+/datum/data/pda/app/nerdle/proc/try_guess(var/guess)
+ if(completed)
+ return FALSE
+
+ if(LAZYLEN(guess) != 5)
+ return FALSE
+
+ var/actual_guess = lowertext(guess)
+
+ serialize_guess(actual_guess)
+ LAZYADD(guesses,actual_guess)
+
+ if(actual_guess == target_word)
+ pda.audible_message("[pda] says, \"congratulations! You WON! A real NERDLE™️ Champ!\"")
+ playsound(pda, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
+ report_guesses()
+ return TRUE
+
+ if(LAZYLEN(guesses) >= max_guesses)
+ pda.audible_message("[pda] says, \"Sorry! You lose! Try again next shift!\"")
+ failure = TRUE
+ playsound(pda, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
+ report_guesses()
+ return FALSE
+
+ return TRUE
+
+/datum/data/pda/app/nerdle/proc/report_guesses()
+ SSnerdle.report_winner_or_loser(LAZYLEN(guesses),failure)
+
+/datum/data/pda/app/nerdle/proc/serialize_guess(var/guess)
+ // We assume that there's 5 letters here, both for the guess and the target word.
+ // If we're getting runtimes and someone forwarded "butt" to here I'm going to smite them down.
+ var/list/out[5]
+ var/list/letter_counts = list() // Track occurrences of each letter in the target word
+
+ // Count count of each letter in the target word
+ for(var/i in 1 to 5)
+ var/them = target_word[i]
+ letter_counts[them] = (letter_counts[them] || 0) + 1
+
+ // First pass: Mark exact matches (NERDLE_YES)
+ for(var/i in 1 to 5)
+ var/us = guess[i]
+ var/them = target_word[i]
+
+ if(us == them)
+ out[i] = NERDLE_YES
+ letter_counts[them] -= 1 // Reduce the count for this letter
+
+ // Second pass: Mark close matches (NERDLE_CLOSE) and invalid matches (NERDLE_NO)
+ for(var/i in 1 to 5)
+ if(out[i]) // Skip already marked letters
+ continue
+
+ var/us = guess[i]
+
+ if(letter_counts[us] && letter_counts[us] > 0)
+ out[i] = NERDLE_CLOSE
+ letter_counts[us] -= 1 // Reduce the count for this letter
+ else
+ out[i] = NERDLE_NO
+
+ LAZYADD(serialized_guesses, list(out)) // Wrap it in a list so it stays a list
+
+/datum/data/pda/app/nerdle/update_ui(mob/user as mob, list/data)
+ data["guesses"] = serialized_guesses
+ data["guesses_raw"] = guesses
+ data["max"] = max_guesses
+ data["used_guesses"] = LAZYLEN(guesses)
+ data["target_word"] = target_word //if people fuck around with tgui to cheat at nerdle then I can't really be assed enough to care. we'll know who you are.
+
+/datum/data/pda/app/nerdle/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
+ if(..())
+ return TRUE
+
+ unnotify()
+
+ . = TRUE
+
+ if(action == "guess")
+ var/guess = params["lastword"]
+ var/did_we_guess = try_guess(guess)
+ return did_we_guess
+
+#undef NERDLE_YES
+#undef NERDLE_NO
+#undef NERDLE_CLOSE
diff --git a/code/modules/pda/pda.dm b/code/modules/pda/pda.dm
index fdaf92ca20..bd75f0b51c 100644
--- a/code/modules/pda/pda.dm
+++ b/code/modules/pda/pda.dm
@@ -47,6 +47,7 @@
new/datum/data/pda/app/messenger,
new/datum/data/pda/app/manifest,
new/datum/data/pda/app/atmos_scanner,
+ new/datum/data/pda/app/nerdle,
new/datum/data/pda/utility/scanmode/notes,
new/datum/data/pda/utility/flashlight)
var/list/shortcut_cache = list()
diff --git a/strings/nerdle_dict.txt b/strings/nerdle_dict.txt
new file mode 100644
index 0000000000..3746ca4e55
--- /dev/null
+++ b/strings/nerdle_dict.txt
@@ -0,0 +1,2348 @@
+aback
+abase
+abate
+abbey
+abbot
+abhor
+abide
+abled
+abode
+abort
+about
+above
+abuse
+abyss
+acorn
+acrid
+actor
+acute
+adage
+adapt
+adept
+admin
+admit
+adobe
+adopt
+adore
+adorn
+adult
+affix
+afire
+afoot
+afoul
+after
+again
+agape
+agate
+agent
+agile
+aging
+aglow
+agony
+agora
+agree
+ahead
+ahelp
+aider
+aisle
+akula
+alarm
+album
+alert
+algae
+alibi
+alien
+align
+alike
+alive
+allay
+alley
+allot
+allow
+alloy
+aloft
+alone
+along
+aloof
+aloud
+alpha
+altar
+alter
+amass
+amaze
+amber
+amble
+amend
+amiss
+amity
+among
+ample
+amply
+amuse
+angel
+anger
+angle
+angry
+angst
+anime
+ankle
+annex
+annoy
+annul
+anode
+antic
+anvil
+aorta
+apart
+aphid
+aping
+apnea
+apple
+apply
+apron
+aptly
+arbor
+ardor
+arena
+argue
+arise
+armor
+aroma
+arose
+array
+arrow
+arson
+artsy
+ascot
+ashen
+aside
+askew
+assay
+asset
+atmos
+atoll
+atone
+attic
+audio
+audit
+augur
+aunty
+avail
+avert
+avian
+avoid
+await
+awake
+award
+aware
+awash
+awful
+awoke
+axial
+axiom
+axion
+azure
+bacon
+badge
+badly
+bagel
+baggy
+baker
+baler
+balmy
+banal
+banjo
+barge
+baron
+basal
+basic
+basil
+basin
+basis
+baste
+batch
+bathe
+baton
+batty
+bawdy
+bayou
+beach
+beady
+beans
+beard
+beast
+beech
+beefy
+befit
+began
+begat
+beget
+begin
+begun
+being
+belch
+belie
+belle
+belly
+below
+bench
+bepis
+beret
+berry
+berth
+beset
+betel
+bevel
+bezel
+bible
+bicep
+biddy
+bigot
+bilge
+billy
+binge
+bingo
+binky
+biome
+birch
+birth
+bison
+bitch
+bitty
+black
+blade
+blame
+bland
+blank
+blare
+blast
+blaze
+bleak
+bleat
+bleed
+bleep
+blend
+bless
+blimp
+blind
+blink
+bliss
+blitz
+bloat
+block
+bloke
+blond
+blood
+bloom
+blown
+bluer
+bluff
+blunt
+blurb
+blurt
+blush
+bnnuy
+board
+boast
+bobby
+bogen
+boney
+bongo
+bonus
+booby
+boost
+booth
+booty
+booze
+boozy
+borax
+borne
+bosom
+bossy
+botch
+bough
+boule
+bound
+bowel
+boxer
+brace
+braid
+brain
+brake
+brand
+brash
+brass
+brave
+bravo
+brawl
+brawn
+bread
+break
+breed
+briar
+bribe
+brick
+bride
+brief
+brine
+bring
+brink
+briny
+brisk
+broad
+broil
+broke
+brood
+brook
+broom
+broth
+brown
+brunt
+brush
+brute
+buddy
+budge
+buggy
+bugle
+build
+built
+bulge
+bulky
+bully
+bunch
+bunny
+buppy
+burly
+burnt
+burst
+bused
+bushy
+bussy
+butch
+butte
+buxom
+buyer
+bylaw
+cabal
+cabby
+cabin
+cable
+cacao
+cache
+cacti
+caddy
+cadet
+cagey
+cairn
+camel
+cameo
+canal
+candy
+canny
+canoe
+canon
+caper
+caput
+carat
+cargo
+carol
+carry
+carve
+caste
+catch
+cater
+catty
+caulk
+cause
+cavil
+cease
+cedar
+cello
+chafe
+chaff
+chain
+chair
+chalk
+champ
+chant
+chaos
+chard
+charm
+chart
+chase
+chasm
+cheap
+cheat
+check
+cheek
+cheer
+chess
+chest
+chick
+chide
+chief
+child
+chili
+chill
+chime
+china
+chirp
+chock
+choir
+choke
+chord
+chore
+chose
+chuck
+chump
+chunk
+churn
+chute
+cider
+cigar
+cinch
+circa
+civic
+civil
+clack
+claim
+clamp
+clang
+clank
+clash
+clasp
+class
+clean
+clear
+cleat
+cleft
+clerk
+click
+cliff
+climb
+cling
+clink
+cloak
+clock
+clone
+close
+cloth
+cloud
+clout
+clove
+clown
+cluck
+clued
+clump
+clung
+coach
+coast
+cobra
+cocoa
+colon
+color
+comet
+comfy
+comic
+comma
+conch
+condo
+conic
+cooch
+copse
+coral
+corer
+corny
+couch
+cough
+could
+count
+coupe
+court
+coven
+cover
+covet
+covey
+cower
+coyly
+crack
+craft
+cramp
+crane
+crank
+crash
+crass
+crate
+crave
+crawl
+craze
+crazy
+creak
+cream
+credo
+creed
+creek
+creep
+creme
+crepe
+crept
+cress
+crest
+crick
+cried
+crier
+crime
+crimp
+crisp
+croak
+crock
+crone
+crony
+crook
+cross
+croup
+crowd
+crown
+crude
+cruel
+crumb
+crump
+crush
+crust
+crypt
+cubic
+cumin
+cummy
+curio
+curly
+curry
+curse
+curve
+curvy
+cutie
+cyber
+cycle
+cynic
+daddy
+daily
+dairy
+daisy
+dally
+dance
+dandy
+datum
+daunt
+dealt
+death
+debar
+debit
+debug
+debut
+decal
+decay
+decor
+decoy
+decry
+defer
+deign
+deity
+delay
+delta
+delve
+demon
+demur
+denim
+dense
+depot
+depth
+derby
+deter
+detox
+deuce
+devil
+diary
+dicey
+digit
+dilly
+dimly
+diner
+dingo
+dingy
+diode
+diona
+dirge
+dirty
+disco
+ditch
+ditto
+ditty
+diver
+dizzy
+dodge
+dodgy
+dogma
+doing
+dolly
+donor
+donut
+dopey
+doubt
+dough
+dowdy
+dowel
+downy
+dowry
+dozen
+draft
+drain
+drake
+drama
+drank
+drape
+drawl
+drawn
+dread
+dream
+dress
+dried
+drier
+drift
+drill
+drink
+drive
+droit
+droll
+drone
+drool
+droop
+dross
+drove
+drown
+druid
+drunk
+dryer
+dryly
+duchy
+dully
+dummy
+dumpy
+dunce
+dusky
+dusty
+dutch
+duvet
+dwarf
+dwell
+dwelt
+dying
+eager
+eagle
+early
+earth
+easel
+eaten
+eater
+ebony
+eclat
+edict
+edify
+eerie
+egret
+eight
+eject
+eking
+elate
+elbow
+elder
+elect
+elegy
+elfin
+elide
+elite
+elope
+elude
+email
+embed
+ember
+emcee
+empty
+enact
+endow
+enema
+enemy
+enjoy
+ennui
+ensue
+enter
+entry
+envoy
+epoch
+epoxy
+equal
+equip
+erase
+erect
+erode
+error
+erupt
+essay
+ester
+ether
+ethic
+ethos
+etude
+evade
+event
+every
+evict
+evoke
+exact
+exalt
+excel
+exert
+exile
+exist
+expel
+extol
+extra
+exult
+eying
+fable
+facet
+faint
+fairy
+faith
+false
+fancy
+fanny
+farce
+fatal
+fatty
+fault
+fauna
+favor
+feast
+fecal
+feign
+fella
+felon
+femme
+femur
+fence
+feral
+ferry
+fetal
+fetch
+fetid
+fetus
+fever
+fewer
+fiber
+fibre
+ficus
+field
+fiend
+fiery
+fifth
+fifty
+fight
+filer
+filet
+filly
+filmy
+filth
+final
+finch
+finer
+first
+fishy
+fixer
+fizzy
+fjord
+flack
+flail
+flair
+flake
+flaky
+flame
+flank
+flare
+flash
+flask
+fleck
+fleet
+flesh
+flick
+flier
+fling
+flint
+flirt
+float
+flock
+flood
+floor
+flora
+floss
+flour
+flout
+flown
+fluff
+fluid
+fluke
+flume
+flung
+flunk
+flush
+flute
+flyer
+foamy
+focal
+focus
+foggy
+foist
+folio
+folly
+foray
+force
+forge
+forgo
+forte
+forth
+forty
+forum
+found
+foyer
+frags
+frail
+frame
+frank
+fraud
+freak
+freed
+freer
+fresh
+friar
+fried
+frill
+frisk
+fritz
+frock
+frond
+front
+frost
+froth
+frown
+froze
+fruit
+fudge
+fugue
+fully
+fungi
+funky
+funny
+furor
+furry
+fussy
+fuzzy
+gaffe
+gaily
+gamer
+gamma
+gamut
+gassy
+gaudy
+gauge
+gaunt
+gauze
+gavel
+gawky
+gayer
+gayly
+gazer
+gecko
+geeky
+geese
+genie
+genre
+ghost
+ghoul
+giant
+giddy
+gipsy
+girly
+girth
+given
+giver
+glade
+gland
+glare
+glass
+glaze
+gleam
+glean
+glide
+glint
+gloat
+globe
+gloom
+glory
+gloss
+glove
+glyph
+gnash
+gnome
+godly
+going
+golem
+golly
+gonad
+goner
+goody
+gooey
+goofy
+goose
+gorge
+gouge
+gourd
+grace
+grade
+graft
+grail
+grain
+grand
+grant
+grape
+graph
+grasp
+grass
+grate
+grave
+gravy
+graze
+great
+greed
+green
+greet
+grief
+grill
+grime
+grimy
+grind
+gripe
+groan
+groin
+groom
+grope
+gross
+group
+grout
+grove
+growl
+grown
+gruel
+gruff
+grunt
+guard
+guava
+guess
+guest
+guide
+guild
+guile
+guilt
+guise
+gulch
+gully
+gumbo
+gummy
+guppy
+gusto
+gusty
+gypsy
+habit
+hairy
+halve
+handy
+happy
+hardy
+harem
+harpy
+harry
+harsh
+haste
+hasty
+hatch
+hater
+haunt
+haute
+haven
+havoc
+hazel
+heady
+heard
+heart
+heath
+heave
+heavy
+hecko
+hedge
+hefty
+heist
+helix
+hello
+hence
+heron
+hilly
+hinge
+hippo
+hippy
+hitch
+hoard
+hobby
+hoist
+holly
+homer
+honey
+honor
+horde
+horny
+horse
+hotel
+hotly
+hound
+house
+hovel
+hover
+howdy
+human
+humid
+humor
+humph
+humus
+hunch
+hunky
+hurry
+husky
+hussy
+hutch
+hydro
+hyena
+hymen
+hyper
+icily
+icing
+ideal
+idiom
+idiot
+idler
+idyll
+igloo
+iliac
+image
+imbue
+impel
+imply
+inane
+inbox
+incur
+index
+inept
+inert
+infer
+ingot
+inlay
+inlet
+inner
+input
+inter
+intro
+ionic
+irate
+irony
+islet
+issue
+itchy
+ivory
+jaunt
+jazzy
+jelly
+jerky
+jetty
+jewel
+jiffy
+joint
+joist
+joker
+jolly
+jones
+joust
+judge
+juice
+juicy
+jumbo
+jumpy
+junta
+junto
+juror
+kappa
+karma
+kayak
+kebab
+khaki
+kinky
+kiosk
+kitty
+knack
+knave
+knead
+kneed
+kneel
+knelt
+knife
+knock
+knoll
+known
+koala
+krill
+label
+labor
+laden
+ladle
+lager
+lance
+lanky
+lapel
+lapse
+large
+larva
+lasso
+latch
+later
+lathe
+latte
+laugh
+layer
+leach
+leafy
+leaky
+leant
+leapt
+learn
+lease
+leash
+least
+leave
+ledge
+leech
+leery
+lefty
+legal
+leggy
+lemon
+lemur
+leper
+level
+lever
+libel
+liege
+light
+liken
+lilac
+limbo
+limit
+linen
+liner
+lingo
+lipid
+lithe
+liver
+livid
+llama
+loamy
+loath
+lobby
+local
+locus
+lodge
+lofty
+logic
+login
+loopy
+loose
+lorry
+loser
+louse
+lousy
+lover
+lower
+lowly
+loyal
+lucid
+lucky
+lumen
+lumpy
+lunar
+lunch
+lunge
+lupus
+lurch
+lurid
+lusty
+lying
+lymph
+lynch
+lyric
+macaw
+macho
+macro
+madam
+madly
+mafia
+magic
+magma
+mahir
+maint
+maize
+major
+maker
+mambo
+mamma
+mammy
+manga
+mange
+mango
+mangy
+mania
+manic
+manly
+manor
+maple
+march
+marry
+marsh
+mason
+masse
+match
+matey
+mauve
+maxim
+maybe
+mayor
+mealy
+meant
+meaty
+mecca
+medal
+media
+medic
+melee
+melon
+mercy
+merge
+merit
+merry
+metal
+meter
+metro
+mhelp
+micro
+midge
+midst
+might
+milky
+mimic
+mince
+miner
+minim
+minor
+minty
+minus
+mirth
+miser
+missy
+mocha
+modal
+model
+modem
+mogul
+moist
+molar
+moldy
+money
+month
+moody
+moose
+moral
+moron
+morph
+mossy
+motel
+motif
+motor
+motto
+moult
+mound
+mount
+mourn
+mouse
+mouth
+mover
+movie
+mower
+mpreg
+mucky
+mucus
+muddy
+mulch
+mummy
+munch
+mural
+murky
+mushy
+music
+musky
+musty
+myrrh
+nadir
+naive
+nanny
+nasal
+nasty
+natal
+naval
+navel
+needy
+neigh
+nerdy
+nerve
+never
+newer
+newly
+nicer
+niche
+niece
+night
+ninja
+ninny
+ninth
+noble
+nobly
+noise
+noisy
+nomad
+noose
+north
+nosey
+notch
+novel
+nudge
+nurse
+nutty
+nylon
+nymph
+oaken
+obese
+occur
+ocean
+octal
+octet
+odder
+oddly
+offal
+offer
+often
+olden
+older
+olive
+ombre
+omega
+onion
+onset
+opera
+opine
+opium
+optic
+orbit
+order
+organ
+other
+otter
+ought
+ounce
+outdo
+outer
+outgo
+ovary
+ovate
+overt
+ovine
+ovoid
+owing
+owner
+oxide
+ozone
+paddy
+pagan
+paint
+paler
+palsy
+panel
+panic
+pansy
+papal
+paper
+parer
+parka
+parry
+parse
+party
+pasta
+paste
+pasty
+patch
+patio
+patsy
+patty
+pause
+pawbs
+payee
+payer
+peace
+peach
+pearl
+pecan
+pedal
+penal
+pence
+penis
+penne
+penny
+perch
+peril
+perky
+pesky
+pesto
+petal
+petty
+phase
+phone
+phony
+photo
+piano
+picky
+piece
+piety
+piggy
+pilot
+pimpy
+pinch
+piney
+pinky
+pinto
+piper
+pique
+pitch
+pithy
+pivot
+pixel
+pixie
+pizza
+place
+plaid
+plain
+plait
+plane
+plank
+plant
+plate
+plaza
+plead
+pleat
+plied
+plier
+pluck
+plumb
+plume
+plump
+plunk
+plush
+poesy
+point
+poise
+poker
+polar
+polka
+polyp
+pooch
+poopy
+poppy
+porch
+poser
+posit
+posse
+pouch
+pound
+pouty
+power
+prank
+prawn
+preen
+press
+price
+prick
+pride
+pried
+prime
+primo
+print
+prior
+prism
+privy
+prize
+probe
+prone
+prong
+proof
+prose
+proud
+prove
+prowl
+proxy
+prude
+prune
+psalm
+pubic
+pudgy
+puffy
+pulpy
+pulse
+punch
+pupal
+pupil
+puppy
+puree
+purer
+purge
+purse
+pushy
+pussy
+putty
+pygmy
+quack
+quail
+quake
+qualm
+quark
+quart
+quash
+quasi
+queen
+queer
+quell
+query
+quest
+queue
+quick
+quiet
+quill
+quilt
+quirk
+quite
+quota
+quote
+quoth
+rabbi
+rabid
+racer
+radar
+radii
+radio
+rainy
+raise
+rajah
+rally
+ralph
+ramen
+ranch
+randy
+range
+rapid
+rarer
+raspy
+ratio
+ratty
+raven
+rayon
+razor
+reach
+react
+ready
+realm
+rearm
+rebar
+rebel
+rebus
+rebut
+recap
+recur
+recut
+reedy
+refer
+refit
+regal
+rehab
+reign
+relax
+relay
+relic
+remit
+renal
+renew
+repay
+repel
+reply
+rerun
+reset
+resin
+retch
+retro
+retry
+reuse
+revel
+revue
+rhino
+rhyme
+rider
+ridge
+rifle
+right
+rigid
+rigor
+rinse
+ripen
+riper
+risen
+riser
+risky
+rival
+river
+rivet
+roach
+roast
+robin
+robot
+rocky
+rodeo
+roger
+rogue
+roomy
+roost
+rotor
+rouge
+rough
+round
+rouse
+route
+rover
+rowdy
+rower
+royal
+ruddy
+ruder
+rugby
+ruler
+rumba
+rumor
+rupee
+rural
+rusty
+sadly
+safer
+saint
+salad
+sally
+salon
+salsa
+salty
+salve
+salvo
+sandy
+saner
+sappy
+sassy
+satin
+satyr
+sauce
+saucy
+sauna
+saute
+savor
+savoy
+savvy
+scald
+scale
+scalp
+scaly
+scamp
+scant
+scare
+scarf
+scary
+scene
+scent
+scion
+scoff
+scold
+scone
+scoop
+scope
+score
+scorn
+scour
+scout
+scowl
+scram
+scrap
+scree
+screw
+scrub
+scrum
+scuba
+sedan
+seedy
+segue
+seize
+semen
+sense
+sepia
+serif
+serum
+serve
+setup
+seven
+sever
+sewer
+shack
+shade
+shady
+shaft
+shake
+shaky
+shale
+shall
+shalt
+shame
+shank
+shape
+shard
+share
+shark
+sharp
+shave
+shawl
+shear
+sheen
+sheep
+sheer
+sheet
+sheik
+shelf
+shell
+shied
+shift
+shine
+shiny
+shire
+shirk
+shirt
+shoal
+shock
+shone
+shook
+shoot
+shore
+shorn
+short
+shout
+shove
+shown
+showy
+shrew
+shrub
+shrug
+shuck
+shunt
+shush
+shyly
+siege
+sieve
+sight
+sigma
+silky
+silly
+since
+sinew
+singe
+siren
+sissy
+sixth
+sixty
+skate
+skier
+skiff
+skill
+skimp
+skirt
+skulk
+skull
+skunk
+slack
+slain
+slang
+slant
+slash
+slate
+slave
+sleek
+sleep
+sleet
+slept
+slice
+slick
+slide
+slime
+slimy
+sling
+slink
+sloop
+slope
+slosh
+sloth
+slump
+slung
+slunk
+slurp
+slush
+slyly
+smack
+small
+smart
+smash
+smear
+smell
+smelt
+smile
+smirk
+smite
+smith
+smock
+smoke
+smoky
+smote
+snack
+snail
+snake
+snaky
+snare
+snarl
+sneak
+sneer
+snide
+sniff
+snipe
+snoop
+snore
+snort
+snout
+snowy
+snuck
+snuff
+soapy
+sober
+soggy
+solar
+solid
+solve
+sonar
+sonic
+sooth
+sooty
+sorry
+sound
+south
+sower
+space
+spade
+spank
+spare
+spark
+spasm
+spawn
+speak
+spear
+speck
+speed
+spell
+spelt
+spend
+spent
+sperm
+spice
+spicy
+spied
+spiel
+spike
+spiky
+spill
+spilt
+spine
+spiny
+spire
+spite
+splat
+split
+spoil
+spoke
+spoof
+spook
+spool
+spoon
+spore
+sport
+spout
+spray
+spree
+sprig
+spunk
+spurn
+spurt
+squad
+squat
+squib
+stack
+staff
+stage
+staid
+stain
+stair
+stake
+stale
+stalk
+stall
+stamp
+stand
+stank
+stare
+stark
+start
+stash
+state
+stave
+stead
+steak
+steal
+steam
+steed
+steel
+steep
+steer
+stein
+stern
+stick
+stiff
+still
+stilt
+sting
+stink
+stint
+stock
+stoic
+stoke
+stole
+stomp
+stone
+stony
+stood
+stool
+stoop
+store
+stork
+storm
+story
+stout
+stove
+strap
+straw
+stray
+strip
+strut
+stuck
+study
+stuff
+stump
+stung
+stunk
+stunt
+style
+suave
+sugar
+suing
+suite
+sulky
+sully
+sumac
+sunny
+super
+surer
+surge
+surly
+sushi
+swami
+swamp
+swarm
+swash
+swath
+swear
+sweat
+sweep
+sweet
+swell
+swept
+swift
+swill
+swine
+swing
+swirl
+swish
+swoon
+swoop
+sword
+swore
+sworn
+swung
+synod
+syrup
+tabby
+table
+taboo
+tacit
+tacky
+taffy
+taint
+taken
+taker
+tally
+talon
+tamer
+tango
+tangy
+taper
+tapir
+tardy
+tarot
+taste
+tasty
+tatty
+taunt
+tawny
+teach
+teary
+tease
+teddy
+teeth
+tempo
+tenet
+tenor
+tense
+tenth
+tepee
+tepid
+terra
+terse
+tesla
+testy
+thank
+theft
+their
+theme
+there
+these
+theta
+thick
+thief
+thigh
+thing
+think
+third
+thong
+thorn
+those
+three
+threw
+throb
+throw
+thrum
+thumb
+thump
+thyme
+tiara
+tibia
+tidal
+tiger
+tight
+tilde
+timer
+timid
+tipsy
+titan
+tithe
+title
+titty
+toast
+today
+toddy
+token
+tonal
+tonga
+tonic
+tooth
+topaz
+topic
+torch
+torso
+torus
+total
+totem
+toter
+touch
+tough
+towel
+tower
+toxic
+toxin
+trace
+track
+tract
+trade
+trail
+train
+trait
+tramp
+trash
+trawl
+tread
+treat
+trend
+triad
+trial
+tribe
+trice
+trick
+tried
+tripe
+trite
+troll
+troop
+trope
+trout
+trove
+truce
+truck
+truer
+truly
+trump
+trunk
+truss
+trust
+truth
+tryst
+tubal
+tuber
+tulip
+tulle
+tumor
+tunic
+turbo
+tutor
+twang
+tweak
+tweed
+tweet
+twice
+twine
+twirl
+twist
+twixt
+tying
+udder
+ulcer
+ultra
+umbra
+uncle
+uncut
+under
+undid
+undue
+unfed
+unfit
+unify
+union
+unite
+unity
+unlit
+unmet
+unset
+untie
+until
+unwed
+unzip
+upper
+upset
+urban
+urine
+usage
+usher
+using
+usual
+usurp
+utile
+utter
+vague
+valet
+valid
+valor
+value
+valve
+vapid
+vapor
+vault
+vaunt
+vegan
+venom
+venue
+verge
+verse
+verso
+verve
+vicar
+video
+vigil
+vigor
+villa
+vinyl
+viola
+viper
+viral
+virgo
+virus
+visit
+visor
+vista
+vital
+vivid
+vixen
+vocal
+vodka
+vogue
+voice
+voila
+vomit
+vored
+vorny
+voter
+vouch
+vowel
+vying
+wacky
+wafer
+wager
+wagon
+waist
+waive
+waltz
+warty
+waste
+watch
+water
+waver
+waxen
+weary
+weave
+wedge
+weedy
+weigh
+weird
+welch
+welsh
+wench
+whack
+whale
+wharf
+wheat
+wheel
+whelp
+where
+which
+whiff
+while
+whine
+whiny
+whirl
+whisk
+white
+whole
+whoop
+whore
+whose
+widen
+wider
+widow
+width
+wield
+wight
+willy
+wimpy
+wince
+winch
+windy
+wiser
+wispy
+witch
+witty
+woken
+woman
+women
+woody
+wooer
+wooly
+woozy
+wordy
+world
+worry
+worse
+worst
+worth
+would
+wound
+woven
+wrack
+wrath
+wreak
+wreck
+wrest
+wring
+wrist
+write
+wrong
+wrote
+wrung
+wryly
+yacht
+yearn
+yeast
+yield
+young
+youth
+zebra
+zesty
+zonal
diff --git a/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_nerdle.tsx b/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_nerdle.tsx
new file mode 100644
index 0000000000..9714535a15
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_nerdle.tsx
@@ -0,0 +1,82 @@
+import { useBackend } from 'tgui/backend';
+import { Box, Input, Section, Stack } from 'tgui-core/components';
+
+type Data = {
+ guesses: number[][]; // Serialized guesses (NERDLE_YES, NERDLE_CLOSE, NERDLE_NO)
+ guesses_raw: string[]; // Raw guesses (letters)
+ max: number; // Maximum number of guesses
+ used_guesses: number; // Number of guesses used
+ target_word: string; // Target word for debugging (optional)
+};
+
+export const pda_nerdle = (props) => {
+ const { act, data } = useBackend();
+
+ const { guesses, guesses_raw, max, used_guesses, target_word } = data;
+
+ const gameOver = used_guesses >= max || guesses_raw.includes(target_word);
+
+ return (
+
+
+
+
+ {guesses.length > 0 ? (
+ guesses.map((guess, index) => (
+
+
+
+ {guess.map((result, i) => (
+
+ {guesses_raw[index][i]}
+
+ ))}
+
+
+
+ ))
+ ) : (
+ No guesses yet!
+ )}
+
+
+
+ );
+};
diff --git a/vorestation.dme b/vorestation.dme
index aff48c2dff..1e54209ba7 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -466,6 +466,7 @@
#include "code\controllers\subsystems\media_tracks.dm"
#include "code\controllers\subsystems\mobs.dm"
#include "code\controllers\subsystems\motion_tracker.dm"
+#include "code\controllers\subsystems\nerdle.dm"
#include "code\controllers\subsystems\nightshift.dm"
#include "code\controllers\subsystems\overlays_ch.dm"
#include "code\controllers\subsystems\overmap_renamer_vr.dm"
@@ -4085,6 +4086,7 @@
#include "code\modules\pda\core_apps.dm"
#include "code\modules\pda\messenger.dm"
#include "code\modules\pda\messenger_plugins.dm"
+#include "code\modules\pda\nerdle.dm"
#include "code\modules\pda\pda.dm"
#include "code\modules\pda\pda_subtypes.dm"
#include "code\modules\pda\pda_tgui.dm"