Port Synthetic Voicebox from The Den/ImpStation/CD #871

Open
OrionTheOreooo wants to merge 26 commits from OrionTheOreooo/Byrd:synth-accents-fixed-20260825 into master
First-time contributor

Short description

!! IMPORTANT !!: This is a "fixed" pr for Byrd-Station/Byrd!866 (aka I didn't just auto pilot on the PR page and Rebase onto the wrong damn branch)
Add Synthetic Voicebox and a passive Malfunctioning addon which applies a light glitch effect on all speech as well as when damaged.

Why we need to add this

No balance changes, just plain roleplay fun

Media (Video/Screenshots)

image
image

Checklist

Breaking changes

  • tweak: Changed DamagedSynthAccent.DamageAtMaxCorruption to a non-nullable field, and given it a default of 100.
  • add: Added PassiveDamagedSynthAccent (Both Component and System) for passive text corruption as though the voice box was damaged.

Ingame Changelog

🆑

  • add: Added Synthetic Voicebox, your voice can now glitch as you take damage! (Values are to be tested and tweaked to player preferences!)
  • add: Added Damaged Synthetic Voicebox, for when you want to glitch a little all the time as well. (for developers, this also comes in the form of PassiveDamagedSynthAccent (component and system) for use elsewhere)
<!-- Link definitions, do not edit --> [guidelines]: https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html [ruleset]: https://rules.byrdstation.space/#h.vigrxrnffwji ## Short description <!-- What do you propose to change with your PR? --> !! IMPORTANT !!: This is a "fixed" pr for Byrd-Station/Byrd!866 (aka I didn't just auto pilot on the PR page and Rebase onto the wrong damn branch) Add Synthetic Voicebox and a passive Malfunctioning addon which applies a light glitch effect on all speech as well as when damaged. ## Why we need to add this <!-- What is the reason for adding these changes? Please post links to Discussions as well as Bug Reports here. Please describe how this will change the game balance. --> No balance changes, just plain roleplay fun ## Media (Video/Screenshots) <!--If your PR contains in-game changes you must provide screenshots/videos of the changes.--> ![image](/attachments/fc8bf4fc-9685-4962-8efd-de9f0380f68f) ![image](/attachments/109a6cb8-5672-4886-9046-f08c29798068) ## Checklist <!-- Check boxes for faster reviewing of your PR --> - [x] I do not require assistance to complete the PR. - [x] I have verified that the changes work before posting/requesting review of my PR. - [x] I have added screenshots/videos of the changes, or this PR does not change in-game mechanics. - [x] I have read the [Pull Request and Changelog Guidelines][guidelines] and [Byrd Station's Contributor Ruleset][ruleset]. ## Breaking changes <!-- List any breaking changes, including namespaces, public class/method/field changes, prototype renames; and provide instructions for fixing them. This will be posted in #codebase-changes. --> - tweak: Changed DamagedSynthAccent.DamageAtMaxCorruption to a non-nullable field, and given it a default of 100. - add: Added PassiveDamagedSynthAccent (Both Component and System) for passive text corruption as though the voice box was damaged. ### Ingame Changelog <!--If you want the players to know about changes made in this PR, specify them using the template outside the comment. Short and informative.--> :cl: - add: Added Synthetic Voicebox, your voice can now glitch as you take damage! (Values are to be tested and tweaked to player preferences!) - add: Added Damaged Synthetic Voicebox, for when you want to glitch a little all the time as well. (for developers, this also comes in the form of PassiveDamagedSynthAccent (component and system) for use elsewhere)
Remove the api bits that I isolated to other class
Some checks failed
Labels: Size / size-label (pull_request_target) Successful in 5s
Labels: PR / labeler (pull_request_target) Successful in 6s
CRLF Check / CRLF Check (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
1612315cb5
Remove leftover methods
Some checks failed
Close PRs on master / run (pull_request_target) Has been skipped
Labels: Size / size-label (pull_request_target) Failing after 3s
Labels: PR / labeler (pull_request_target) Successful in 3s
CRLF Check / CRLF Check (pull_request) Failing after 2m7s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 2m12s
RSI Validator / Validate RSIs (pull_request) Successful in 2m31s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m21s
YAML Linter / YAML Linter (pull_request) Successful in 8m26s
Test Packaging / Test Packaging (pull_request) Successful in 17m59s
e6028c01e1
Owner

I don't think damaged borgs speech should be reduced to nothing at low damage, even at high damage.
Steps to reproduce: Play as a cyborg, get damaged (above 30, but even below 30 it sometimes just doesn't send the message, but does the speak sound) say a long message but get nothing (might need a few attempts).
empty message

I don't think damaged borgs speech should be reduced to nothing at low damage, even at high damage. Steps to reproduce: Play as a cyborg, get damaged (above 30, but even below 30 it sometimes just doesn't send the message, but does the speak sound) say a long message but get nothing (might need a few attempts). ![empty message](/attachments/cc2a6902-5bb6-445b-a80b-68e9e95af2bf)
@ -122,4 +116,0 @@
damageAtMaxCorruption = _destructibleSystem.DestroyedAt(ent, destructible);
}
Owner

Why?

Why?
EchoOfNothing marked this conversation as resolved
@ -56,3 +56,3 @@
}
// Corrupt due to damage (drop, repeat, replace with symbols)
args.Message = CorruptDamage(args.Message, damage, ent);
args.Message = CorruptDamage(args.Message, damage, ref ent.Comp);
Owner

Changes to non-Byrd code should be marked with // Byrd, you can also add an optional comment like so // Byrd - [comment]

Changes to non-Byrd code should be marked with `// Byrd`, you can also add an optional comment like so `// Byrd - [comment]`
EchoOfNothing marked this conversation as resolved
@ -0,0 +49,4 @@
return outMsg.ToString();
}
private string CorruptLetter(char letter)
Owner

This is basically a copy and paste of CorruptLetterDamage in DamagedSiliconAccentSystem. I would prefer to avoid copy and pasted code.

This is basically a copy and paste of `CorruptLetterDamage` in `DamagedSiliconAccentSystem`. I would prefer to avoid copy and pasted code.
EchoOfNothing marked this conversation as resolved
@ -12,2 +12,3 @@
/// </summary>
[DataField]
[DataField("enableDamageCorruption")]
[ViewVariables(VVAccess.ReadWrite)]
Owner

This changes nothing. Just makes it more verbose, which I do not like.

This changes nothing. Just makes it more verbose, which I do not like.
Author
First-time contributor

Apologies, this was a leftover from trying to get the YAML config to be used (as for some reason the YAML was/is not being used for to fill those values, resulting in NULL (and the system not doing anything))

Apologies, this was a leftover from trying to get the YAML config to be used (as for some reason the YAML was/is not being used for to fill those values, resulting in NULL (and the system not doing anything))
EchoOfNothing marked this conversation as resolved
@ -34,1 +36,3 @@
public FixedPoint2? DamageAtMaxCorruption;
[DataField("damageAtMaxCorruption")]
[ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 DamageAtMaxCorruption = 100;
Owner

Why?

Why?
EchoOfNothing marked this conversation as resolved
@ -0,0 +11,4 @@
/// Determines if text should be corrupted, regardless of damage or power.
/// </summary>
[DataField("enablePassiveCorruption")]
[ViewVariables(VVAccess.ReadWrite)]
Owner

Just put [DataField], no need to make it overly verbose.

Just put `[DataField]`, no need to make it overly verbose.
EchoOfNothing marked this conversation as resolved
Echo's fixes (or most of them)
Some checks failed
Labels: Size / size-label (pull_request_target) Successful in 3s
Labels: PR / labeler (pull_request_target) Successful in 4s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 4m5s
CRLF Check / CRLF Check (pull_request) Failing after 5m10s
RSI Validator / Validate RSIs (pull_request) Successful in 5m52s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m34s
YAML Linter / YAML Linter (pull_request) Successful in 11m47s
Test Packaging / Test Packaging (pull_request) Successful in 28m11s
a5d919bd7c
@ -60,3 +60,3 @@
}
public string CorruptPower(string message, float chargeLevel, DamagedSiliconAccentComponent comp)
public string CorruptPower(string message, float chargeLevel, ref DamagedSiliconAccentComponent comp) // Byrd - Only a component reference is needed
Owner

Why ref?

Why `ref`?
@ -113,3 +117,4 @@
{
var outMsg = new StringBuilder();
// Linear interpolation of character damage probability
Owner

Why did this comment jump up to here?

Why did this comment jump up to here?
@ -127,2 +132,2 @@
var damagePercent = Math.Clamp((float)totalDamage / (float)damageAtMaxCorruption, 0, 1);
var chanceToCorruptLetter = damagePercent * ent.Comp.MaxDamageCorruption;
var damagePercent = Math.Clamp((float) totalDamage / (float) damageAtMaxCorruption, 0, 1);
var chanceToCorruptLetter = damagePercent * damageAtMaxCorruption;
Owner

Why did you change MaxDamageCorruption to damageAtMaxCorruption?

Why did you change `MaxDamageCorruption` to `damageAtMaxCorruption`?
@ -32,3 +32,3 @@
/// </summary>
[DataField]
public FixedPoint2? DamageAtMaxCorruption;
public FixedPoint2 DamageAtMaxCorruption = 100; // Byrd - Set to Non Null Value, YAML wasn't reading at time
Owner

I don't really see a good reason to make it non-nullable. I don't have any issues with yaml reading it and I never had. Are you sure you didn't make any types in yaml?

I don't really see a good reason to make it non-nullable. I don't have any issues with yaml reading it and I never had. Are you sure you didn't make any types in yaml?
@ -0,0 +18,4 @@
/// </summary>
[DataField]
public float PassiveCorruptionChance = 0.1f;
}
Owner

Have you considered adding a new field to DamagedSiliconAccentComponent like minCorruption or something similar?

Have you considered adding a new field to `DamagedSiliconAccentComponent` like `minCorruption` or something similar?
@ -79,1 +79,4 @@
trait-british-desc = You speak proper, unlike those bloody yanks.
trait-syntheticvb-name = Synthetic Voicebox
trait-syntheticvb-desc = Your vocal apparatus is itself synthetic, and starts to malfunction when you are injured.
Owner

This if for a _CD trait.

This if for a `_CD` trait.
@ -80,0 +82,4 @@
trait-syntheticvb-desc = Your vocal apparatus is itself synthetic, and starts to malfunction when you are injured.
trait-damagedsyntheticvb-name = Malfunctioning Synthetic Voicebox
trait-damagedsyntheticvb-desc = Your Synthetic Voicebox, either through time or damage, has started to malfunction.
Owner

trait-damagedsyntheticvb-name is for DamagedSyntheticVoicebox which is located in Resources/Prototypes/_Byrd/Traits/speech.yml, meaning you should put those under _Byrd since this is for a Byrd specific trait.

`trait-damagedsyntheticvb-name` is for `DamagedSyntheticVoicebox` which is located in `Resources/Prototypes/_Byrd/Traits/speech.yml`, meaning you should put those under `_Byrd` since this is for a Byrd specific trait.
Remove ref, to align with function signature (I read when and when not to use that!)
Some checks failed
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
Labels: Size / size-label (pull_request_target) Has been cancelled
CRLF Check / CRLF Check (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
Labels: PR / labeler (pull_request_target) Has been cancelled
90513b23d9
OrionTheOreooo force-pushed synth-accents-fixed-20260825 from 90513b23d9
Some checks failed
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
Labels: Size / size-label (pull_request_target) Has been cancelled
CRLF Check / CRLF Check (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
Labels: PR / labeler (pull_request_target) Has been cancelled
to 4440ae3015
Some checks failed
Labels: Size / size-label (pull_request_target) Successful in 50s
Labels: PR / labeler (pull_request_target) Successful in 50s
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
CRLF Check / CRLF Check (pull_request) Has been cancelled
2026-08-31 16:47:12 +00:00
Compare
Remove the api bits that I isolated to other class
Some checks failed
Labels: Size / size-label (pull_request_target) Successful in 5s
Labels: PR / labeler (pull_request_target) Successful in 6s
CRLF Check / CRLF Check (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
1612315cb5
Remove leftover methods
Some checks failed
Close PRs on master / run (pull_request_target) Has been skipped
Labels: Size / size-label (pull_request_target) Failing after 3s
Labels: PR / labeler (pull_request_target) Successful in 3s
CRLF Check / CRLF Check (pull_request) Failing after 2m7s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 2m12s
RSI Validator / Validate RSIs (pull_request) Successful in 2m31s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m21s
YAML Linter / YAML Linter (pull_request) Successful in 8m26s
Test Packaging / Test Packaging (pull_request) Successful in 17m59s
e6028c01e1
Echo's fixes (or most of them)
Some checks failed
Labels: Size / size-label (pull_request_target) Successful in 3s
Labels: PR / labeler (pull_request_target) Successful in 4s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 4m5s
CRLF Check / CRLF Check (pull_request) Failing after 5m10s
RSI Validator / Validate RSIs (pull_request) Successful in 5m52s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m34s
YAML Linter / YAML Linter (pull_request) Successful in 11m47s
Test Packaging / Test Packaging (pull_request) Successful in 28m11s
a5d919bd7c
Remove ref, to align with function signature (I read when and when not to use that!)
Some checks failed
RGA schema validator / YAML RGA schema validator (pull_request) Has been cancelled
RSI Validator / Validate RSIs (pull_request) Has been cancelled
Map file schema validator / YAML map schema validator (pull_request) Has been cancelled
YAML Linter / YAML Linter (pull_request) Has been cancelled
Labels: Size / size-label (pull_request_target) Has been cancelled
CRLF Check / CRLF Check (pull_request) Has been cancelled
Test Packaging / Test Packaging (pull_request) Has been cancelled
Labels: PR / labeler (pull_request_target) Has been cancelled
90513b23d9
Merge branch 'synth-accents-fixed-20260825' of https://git.byrdstation.space/OrionTheOreooo/Byrd into synth-accents-fixed-20260825
Some checks failed
Labels: PR / labeler (pull_request_target) Successful in 5s
Labels: Size / size-label (pull_request_target) Successful in 3s
CRLF Check / CRLF Check (pull_request) Successful in 2m24s
Test Packaging / Test Packaging (pull_request) Failing after 4m18s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 5m1s
RSI Validator / Validate RSIs (pull_request) Successful in 5m40s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m46s
YAML Linter / YAML Linter (pull_request) Successful in 7m47s
71c870651a
Forgot the omu comments
All checks were successful
Labels: Size / size-label (pull_request_target) Successful in 58s
Labels: PR / labeler (pull_request_target) Successful in 59s
CRLF Check / CRLF Check (pull_request) Successful in 3m44s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 5m4s
RSI Validator / Validate RSIs (pull_request) Successful in 5m43s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m20s
YAML Linter / YAML Linter (pull_request) Successful in 7m58s
Test Packaging / Test Packaging (pull_request) Successful in 18m27s
3d0e61b551
@ -129,3 +156,3 @@
foreach (var letter in message)
{
if (_random.Prob(chanceToCorruptLetter)) // Corrupt!
if (_random.Prob((float) chanceToCorruptLetter)) // Corrupt!
Owner

(float) here is redundant.

`(float)` here is redundant.
OrionTheOreooo marked this conversation as resolved
@ -126,3 +153,3 @@
// Linear interpolation of character damage probability
var damagePercent = Math.Clamp((float)totalDamage / (float)damageAtMaxCorruption, 0, 1);
var damagePercent = Math.Clamp((float) totalDamage / (float) damageAtMaxCorruption, 0, 1);
var chanceToCorruptLetter = damagePercent * ent.Comp.MaxDamageCorruption;
Owner

You can do something like this:

if(ent.Comp.MinCorruptionChance != null)
    chanceToCorruptLetter = Math.Max(chanceToCorruptLetter, (float)ent.Comp.MinCorruptionChance);
You can do something like this: ``` if(ent.Comp.MinCorruptionChance != null) chanceToCorruptLetter = Math.Max(chanceToCorruptLetter, (float)ent.Comp.MinCorruptionChance); ```
Author
First-time contributor

This is just how the default system for borgs did it, and I assumed it working, the passive corruption chances should be different to the active methods I believe

This is just how the default system for borgs did it, and I assumed it working, the passive corruption chances should be different to the active methods I believe
Owner

Both work, depends on what effect you want to achieve.

Both work, depends on what effect you want to achieve.
OrionTheOreooo marked this conversation as resolved
@ -81,0 +89,4 @@
/// The likely hood a character will be corrupted passively
/// </summary>
[DataField]
public float PassiveCorruptionChance = 0.1f;
Owner

PassiveCorruptionChance can be null or default to 0 by default and then be set by the trait when needed (optionally can also rename this to MinCorruptionChance). This approach will make EnablePassiveCorruption no longer needed.

`PassiveCorruptionChance` can be null or default to 0 by default and then be set by the trait when needed (optionally can also rename this to `MinCorruptionChance`). This approach will make `EnablePassiveCorruption` no longer needed.
OrionTheOreooo marked this conversation as resolved
@ -10,0 +20,4 @@
components:
- type: DamagedSiliconAccent
enablePassiveCorruption: true
enableChargeCorruption: false
Owner

This will overwrite DamagedSiliconAccent defined by SyntheticVoicebox.

This will overwrite `DamagedSiliconAccent` defined by `SyntheticVoicebox`.
Author
First-time contributor

Please explain, I'm unfamiliar as to why this would overwrite like this! I believed it would make its own instance and attach it on top, allowing for both effects to stack.

Please explain, I'm unfamiliar as to why this would overwrite like this! I believed it would make its own instance and attach it on top, allowing for both effects to stack.
Owner

SyntheticVoicebox trait will initialize, add its version of DamagedSiliconAccent component to the entity. Then DamagedSyntheticVoicebox will initialize and replace DamagedSiliconAccent with its version. That's just how traits are currently implemented. The issue you are experiencing comes from the fact that DamagedSyntheticVoicebox doesn't have damageAtMaxCorruption, meaning it will be set to null when DamagedSyntheticVoicebox initializes.

`SyntheticVoicebox` trait will initialize, add its version of `DamagedSiliconAccent` component to the entity. Then `DamagedSyntheticVoicebox` will initialize and replace `DamagedSiliconAccent` with its version. That's just how traits are currently implemented. The issue you are experiencing comes from the fact that `DamagedSyntheticVoicebox` doesn't have `damageAtMaxCorruption`, meaning it will be set to null when `DamagedSyntheticVoicebox` initializes.
@ -10,0 +21,4 @@
- type: DamagedSiliconAccent
enablePassiveCorruption: true
enableChargeCorruption: false
countsTowardsMaxTraits: false # Omustation - Don't count accents towards max traits
Owner

# [Fork name] is added when you are making change to code that originates from a different fork (port). In this case you are adding new code and not modifying existing code, so I don't see where # Omustation - Don't count accents towards max traits would come from.

`# [Fork name]` is added when you are making change to code that originates from a different fork (port). In this case you are adding new code and not modifying existing code, so I don't see where `# Omustation - Don't count accents towards max traits` would come from.
OrionTheOreooo marked this conversation as resolved
All checks were successful
Labels: Size / size-label (pull_request_target) Successful in 58s
Labels: PR / labeler (pull_request_target) Successful in 59s
CRLF Check / CRLF Check (pull_request) Successful in 3m44s
RGA schema validator / YAML RGA schema validator (pull_request) Successful in 5m4s
RSI Validator / Validate RSIs (pull_request) Successful in 5m43s
Map file schema validator / YAML map schema validator (pull_request) Successful in 9m20s
YAML Linter / YAML Linter (pull_request) Successful in 7m58s
Test Packaging / Test Packaging (pull_request) Successful in 18m27s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u "synth-accents-fixed-20260825:OrionTheOreooo-synth-accents-fixed-20260825"
git switch "OrionTheOreooo-synth-accents-fixed-20260825"
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Byrd-Station/Byrd!871
No description provided.