Skip to content

Commit

Permalink
Short EAL (#19895)
Browse files Browse the repository at this point in the history
* EAL is now much shorter to people who can't understand it, to
represent how effective it is at compressing communicated datapackets.
* Fixed scrambled languages causing double spaces and uncapitalized
words.


Showing how the shortened message looks:

![image](https://github.com/user-attachments/assets/c359dcca-8a48-4007-8243-72679a2dd88e)

![image](https://github.com/user-attachments/assets/26ebcab7-265a-4c5a-a13b-ea18ff56e8f8)

Showing the effect of the bugfix:

![image](https://github.com/user-attachments/assets/9cd19a05-392e-49b1-a47f-7df1c0f538b1)

---------

Signed-off-by: Geeves <[email protected]>
Co-authored-by: Fluffy <[email protected]>
  • Loading branch information
Geevies and FluffyGhoster committed Sep 21, 2024
1 parent 4dee47e commit 6572cf3
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 51 deletions.
185 changes: 135 additions & 50 deletions code/modules/mob/language/language.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,77 @@
*/

/datum/language
var/name = "an unknown language" // Fluff name of language if any.
var/short // a shortened name, for use when languages need to be identified
var/desc = "A language." // Short description for 'Check Languages'.
var/list/speech_verb = list("says") // 'says', 'hisses', 'farts'.)
var/list/ask_verb = list("asks") // Used when sentence ends in a ?
var/list/exclaim_verb = list("exclaims") // Used when sentence ends in a !
var/list/shout_verb = list("shouts", "yells", "screams") //Used when a sentence ends in !!
var/list/whisper_verb = null // Optional. When not specified speech_verb + quietly/softly is used instead.
var/list/signlang_verb = list("signs") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
/// Fluff name of language if any.
var/name = "an unknown language"

/// a shortened name, for use when languages need to be identified
var/short

/// Short description for 'Check Languages'.
var/desc = "A language."

/// 'says', 'hisses', 'farts'.
var/list/speech_verb = list("says")

/// Used when sentence ends in a ?
var/list/ask_verb = list("asks")

/// Used when sentence ends in a !
var/list/exclaim_verb = list("exclaims")

/// Used when a sentence ends in !!
var/list/shout_verb = list("shouts", "yells", "screams")

/// Optional. When not specified speech_verb + quietly/softly is used instead.
var/list/whisper_verb = null

/// list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
var/list/signlang_verb = list("signs")

/// The verb displayed when a user sings their message
var/list/sing_verb = list("sings")
var/list/sign_adv_length = list(" briefly", " a short message", " a message", " a lengthy message", " a very lengthy message") // 5 messages changing depending on the length of the signed language. A space should be added before the sentence as shown
var/colour = "body" // CSS style to use for strings in this language.
var/written_style // CSS style used when writing language down, can't be written if null
var/key = "x" // Character used to speak in language eg. :o for Unathi.
var/flags = 0 // Various language flags.
var/native // If set, non-native speakers will have trouble speaking.
var/list/syllables // Used when scrambling text for a non-speaker.
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word
var/machine_understands = TRUE // Whether machines can parse and understand this language

/// 5 messages changing depending on the length of the signed language. A space should be added before the sentence as shown
var/list/sign_adv_length = list(" briefly", " a short message", " a message", " a lengthy message", " a very lengthy message")

/// CSS style to use for strings in this language.
var/colour = "body"

/// CSS style used when writing language down, can't be written if null
var/written_style

/// Character used to speak in language eg. :o for Unathi.
var/key = "x"

/// Various language flags.
var/flags = 0

/// If set, non-native speakers will have trouble speaking.
var/native

/// Used when scrambling text for a non-speaker.
var/list/syllables

/// Likelihood of getting a period and a space in the random scramble string
var/period_chance = 5

/// Likelihood of getting a space in the random scramble string
var/space_chance = 55

/// List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word
var/list/partial_understanding

/// Whether machines can parse and understand this language
var/machine_understands = TRUE

/// Whether the accent tag will display when this language is used
var/allow_accents = FALSE
var/always_parse_language = FALSE // forces the language to parse for language keys even when a default is set
var/list/scramble_cache = list() // A map of unscrambled words -> scrambled words, for scrambling.

/// forces the language to parse for language keys even when a default is set
var/always_parse_language = FALSE

/// A map of unscrambled words -> scrambled words, for scrambling.
var/list/scramble_cache = list()

/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2)
if(!syllables || !syllables.len)
Expand All @@ -47,42 +95,61 @@

return "[trim(full_name)]"

/// Scrambles the spoken line by looping through every word in the line, calling scramble_word, and then returning the final result
/datum/language/proc/scramble(var/input, var/list/known_languages)

// the chance that someone will recognize one of the words
var/understand_chance = 0
for(var/datum/language/L in known_languages)
if(LAZYACCESS(partial_understanding, L.name))
understand_chance += partial_understanding[L.name]

// singing automatically adds musical notes to the line, we don't want to scramble those
var/static/list/music_notes = list("\u2669", "\u266A", "\u266B")

var/list/words = splittext(input, " ")
// splits the line into a list of words
var/list/words_in_line = splittext(input, " ")

// this list will be populated by the word created below
var/list/scrambled_text = list()
var/new_sentence = 0
for(var/w in words)
var/nword = "[w] "
var/input_ending = copytext(w, length(w))
var/ends_sentence = findtext(".?!",input_ending)
if(!prob(understand_chance) && !(w in music_notes))
nword = scramble_word(w)
if(new_sentence)
nword = capitalize(nword)
new_sentence = FALSE
if(ends_sentence)
nword = trim(nword)
nword = "[nword][input_ending] "

if(ends_sentence)
new_sentence = TRUE
// marks the start of a new sentence in the for loop
var/new_sentence = FALSE

scrambled_text += nword
// loop through the list of words, scrambling it if the listener doesn't understand it, just putting it in if they can partially understand it
var/word_index = 1
for(var/word in words_in_line)
var/list/scramble_results = process_word_prescramble(word, "[word] ", word_index, new_sentence, understand_chance, music_notes)
var/new_word = scramble_results[1]
new_sentence = scramble_results[2]
scrambled_text += new_word
word_index++

. = jointext(scrambled_text, null)
. = capitalize(.)
. = trim(.)

/// Handles the word before it's scrambled, and then scrambles it if necessary. Returns the new word as the first result, and whether it's a new sentence or not as the second
/datum/language/proc/process_word_prescramble(var/original_word, var/new_word, var/word_index, var/new_sentence, var/understand_chance, var/list/music_notes)
var/input_ending = copytext(original_word, length(original_word))
var/ends_sentence = findtext(".?!", input_ending)
if(!prob(understand_chance) && !(original_word in music_notes))
new_word = scramble_word(original_word)
if(new_sentence)
new_word = capitalize(new_word)
new_sentence = FALSE
if(ends_sentence)
new_word = trim(new_word)
new_word = "[new_word][input_ending] "

if(ends_sentence)
new_sentence = TRUE

return list(new_word, new_sentence)

/// Scrambles one single word by using the syllables within the syllable list to construct a new word of approximately the same length
/datum/language/proc/scramble_word(var/input)
if(!syllables || !syllables.len)
if(!length(syllables))
return stars(input)

// If the input is cached already, move it to the end of the cache and return it
Expand All @@ -93,29 +160,47 @@
return n

var/input_size = length(input)
var/input_size_required = scrambled_word_size_requirement(input_size)
var/scrambled_text = ""
var/capitalize = 0
var/capitalize = FALSE

while(length(scrambled_text) < input_size)
// loops until the size of the text we've constructed is bigger than the word we're scrambling
while(length(scrambled_text) < input_size_required)
// selects one of the syllables out of the syllable list
var/next = pick(syllables)

// if we're starting a new sentence, capitalize the first word
if(capitalize)
next = capitalize(next)
capitalize = 0
capitalize = FALSE

// adds the picked syllable to the scramble list
scrambled_text += next
var/chance = rand(100)
if(chance <= 5)
scrambled_text += ". "
capitalize = 1
else if(chance > 5 && chance <= space_chance)
scrambled_text += " "

// we don't want to add any additional text if it pushes us over the size of the word itself,
// otherwise the next word won't be capitalized, or will have a double space in front of itself
if(length(scrambled_text) < input_size_required - 2)
// returns a value between 1 and 100, which will be used to determine if we should add a period and start a new word
var/chance = rand(100)

// adds a period and starts a new sentence
if(chance <= period_chance)
scrambled_text += ". "
capitalize = TRUE
// just adds a space
else if(chance <= space_chance)
scrambled_text += " "

// Add it to cache, cutting old entries if the list is too long
scramble_cache[input] = scrambled_text
if(scramble_cache.len > SCRAMBLE_CACHE_LEN)
scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1)
if(length(scramble_cache) > SCRAMBLE_CACHE_LEN)
scramble_cache.Cut(1, length(scramble_cache) - (SCRAMBLE_CACHE_LEN - 1))

return scrambled_text

/datum/language/proc/scrambled_word_size_requirement(var/input_size)
return input_size

/datum/language/proc/format_message(message, verb)
return "[verb], <span class='message'><span class='[colour]'>\"[capitalize(message)]\"</span></span>"

Expand Down
21 changes: 20 additions & 1 deletion code/modules/mob/language/station.dm
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,28 @@
key = "6"
flags = RESTRICTED | NO_STUTTER | TCOMSSIM
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz")
space_chance = 10
period_chance = 0
space_chance = 0

/datum/language/machine/get_random_name()
if(prob(70))
return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
return pick(ai_names)

// we're trimming out the punctuation and not readding it, so we need to readd it at the very end
/datum/language/machine/scramble(var/input, var/list/known_languages)
. = ..()
return formalize_text(.)

/datum/language/machine/process_word_prescramble(var/original_word, var/new_word, var/word_index, var/new_sentence, var/understand_chance, var/list/music_notes)
// we drop every second word to make the resulting message shorter, to represent the effective compression of EAL
if(word_index % 2)
if(!prob(understand_chance) && !(original_word in music_notes))
new_word = trim(scramble_word(original_word))
else
new_word = ""
return list(new_word, new_sentence)

// we don't care about the input_size at all, we just want one syllable used
/datum/language/machine/scrambled_word_size_requirement(var/input_size)
return 1
7 changes: 7 additions & 0 deletions html/changelogs/geeves-short_eal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
author: Geeves

delete-after: True

changes:
- rscadd: "EAL is now much shorter to people who can't understand it, to represent how effective it is at compressing communicated datapackets."
- bugfix: "Fixed scrambled languages causing double spaces and uncapitalized words."

0 comments on commit 6572cf3

Please sign in to comment.