diff --git a/baystation12.dme b/baystation12.dme
index cbc43ffe2b6b0..2846d4bf34574 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -3032,6 +3032,7 @@
#include "code\modules\shuttles\shuttles_multi.dm"
#include "code\modules\skrell\skrell_rigs.dm"
#include "code\modules\species\species.dm"
+#include "code\modules\species\species_age_comparison.dm"
#include "code\modules\species\species_attack.dm"
#include "code\modules\species\species_getters.dm"
#include "code\modules\species\species_grab.dm"
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 35317c9bab2ef..356e64e6b906c 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -348,6 +348,11 @@
var/show_descs = show_descriptors_to(user)
if(show_descs)
msg += SPAN_NOTICE("[jointext(show_descs, "
")]")
+
+ var/age_diff = species.get_age_comparison_string(src, user)
+ if (age_diff)
+ msg += "
[SPAN_NOTICE(age_diff)]"
+
to_chat(user, SPAN_INFO(jointext(msg, null)))
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
diff --git a/code/modules/species/species_age_comparison.dm b/code/modules/species/species_age_comparison.dm
new file mode 100644
index 0000000000000..02bd5bce7529c
--- /dev/null
+++ b/code/modules/species/species_age_comparison.dm
@@ -0,0 +1,63 @@
+/// List (string => integer). Map of descriptive words to the age threshhold to display these words. Age threshhold is the _highest_ age that can use this descriptor. Descriptors should make grammatical sense when used in the following sentence: "They are of [X] age for a [species]."
+/datum/species/var/list/age_descriptors = list(
+ "very young" = 20,
+ "young" = 40,
+ "moderate" = 60,
+ "old" = 80,
+ "very old" = 100,
+ "ancient" = INFINITY
+)
+
+
+/// List (string => integer). Map of descriptive words to the age different threshhold to display these words. Age difference threshhold is the _highest_ number that can use this descriptor. Descriptors should make grammatical sence when used in the following sentence: "They are [X] you."
+/datum/species/var/list/age_diff_descriptors = list(
+ "much younger than" = -15,
+ "younger than" = -10,
+ "slightly younger than" = -5,
+ "around the same age as" = 5,
+ "slightly older than" = 10,
+ "older than" = 15,
+ "much older than" = INFINITY
+)
+
+
+/// Boolean. If set, allows other species to see age descriptions.
+/datum/species/var/show_age_to_other_species = FALSE
+
+
+/datum/species/proc/get_age_comparison_string(mob/living/carbon/human/observed, mob/living/carbon/human/observer)
+ if (!age_descriptors || !age_diff_descriptors || !istype(observed) || observed.isSynthetic())
+ return
+ if (!show_age_to_other_species && name != observer.get_species())
+ return
+
+ var/observed_real_age = observed.age + observed.changed_age
+ var/observer_real_age = observer.age + observer.changed_age
+ var/age_diff
+ var/age_percentile = round((observed_real_age / max_age) * 100)
+ var/age_descriptor
+ var/age_diff_descriptor
+
+ for (var/descriptor in age_descriptors)
+ if (age_percentile > age_descriptors[descriptor])
+ continue
+ age_descriptor = descriptor
+ break
+ if (!age_descriptor)
+ age_descriptor = age_descriptors[length(age_descriptors)]
+
+ if (istype(observer) && observed.get_species() == observer.get_species() && !observer.isSynthetic())
+ age_diff = observed_real_age - observer_real_age
+ for (var/descriptor in age_diff_descriptors)
+ if (age_diff > age_diff_descriptors[descriptor])
+ continue
+ age_diff_descriptor = descriptor
+ break
+ if (!age_diff_descriptor)
+ age_diff_descriptor = age_diff_descriptors[length(age_diff_descriptors)]
+
+ var/datum/pronouns/pronouns = observed.choose_from_pronouns()
+ if (age_diff_descriptor)
+ return "[pronouns.He] [pronouns.is] of [age_descriptor] age for a [name], [age_diff_descriptor] you."
+ else if (age_descriptor)
+ return "[pronouns.He] [pronouns.is] of [age_descriptor] age for a [name]."
diff --git a/code/modules/species/station/lizard.dm b/code/modules/species/station/lizard.dm
index 09e0c98b5bb66..1a80f22c9f552 100644
--- a/code/modules/species/station/lizard.dm
+++ b/code/modules/species/station/lizard.dm
@@ -170,6 +170,8 @@
/obj/item/clothing = /obj/decal/cleanable/blood/tracks/claw // Needs to apply to both shoes and space suits.
)
+ show_age_to_other_species = TRUE
+
/datum/species/unathi/equip_survival_gear(mob/living/carbon/human/H)
..()
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)
diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm
index 126cfdded4b2b..c74f5635b1d15 100644
--- a/code/modules/species/station/monkey.dm
+++ b/code/modules/species/station/monkey.dm
@@ -57,6 +57,8 @@
ingest_amount = 6
+ show_age_to_other_species = TRUE
+
/datum/species/monkey/New()
equip_adjust = list(
slot_l_hand_str = list("[NORTH]" = list("x" = 1, "y" = 3), "[EAST]" = list("x" = -3, "y" = 2), "[SOUTH]" = list("x" = -1, "y" = 3), "[WEST]" = list("x" = 3, "y" = 2)),
diff --git a/code/modules/species/station/station.dm b/code/modules/species/station/station.dm
index c76d964a1e3fe..a1b28e47afac3 100644
--- a/code/modules/species/station/station.dm
+++ b/code/modules/species/station/station.dm
@@ -81,6 +81,8 @@
/singleton/emote/exertion/synthetic/creak
)
+ show_age_to_other_species = TRUE
+
/datum/species/human/get_bodytype(mob/living/carbon/human/H)
return SPECIES_HUMAN