atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0

Commit 2d9074e0b4de

tarball

atagen <boss@atagen.co>2026-10-13 12:37 UTC

4 files changed+31-2
game: let lotion soothe a friction burn

Ice was the only cure, so a burned run with no packs carried halved gains until it found one. Lotion is the weakest lube and had nothing to recommend it, so it now soothes the burn on the stroke it is used and never causes one.
Modified file: src/game/items.rs+3 additions−1 deletions
@@ -116,7 +116,9 @@ impl Item {
116116 Self::TeapotSpout => "Does nothing. Cannot be dropped.",
117117 Self::BabyOil => "Smooth. +1. One unit per jelq.",
118118 Self::CoconutOil => "+3. Solid until it matters. Suspicious at Nan's.",
119- Self::Lotion => "Handy. +0, and it chafes, so each jelq costs an extra stamina.",
119+ Self::Lotion => {
120+ "Handy. +0, and it chafes, so each jelq costs an extra stamina. Soothes a friction burn."
121+ }
120122 Self::Vaseline => "+2. Raises suspicion everywhere.",
121123 Self::EnergyDrink => "technique=energy. +3 stamina. Tastes like a battery.",
122124 }
Modified file: src/game/notice.rs+2 additions
@@ -18,6 +18,7 @@ pub enum Notice {
1818 RunningLong(Floor),
1919 LastTurn,
2020 SkinGivingWay,
21+ BurnSoothed,
2122 }
2223
2324 impl Notice {
@@ -45,6 +46,7 @@ impl Notice {
4546 },
4647 Self::LastTurn => "This is the last turn on this floor. Leave now or be found.",
4748 Self::SkinGivingWay => "the skin is giving way",
49+ Self::BurnSoothed => "the lotion has soothed the friction burn",
4850 }
4951 }
5052 }
Modified file: src/game/progress.rs+5 additions−1 deletions
@@ -37,7 +37,11 @@ impl Run {
3737 }
3838 self.body.jelq_grip = Some(self.body.grip);
3939 self.body.friction = (self.body.friction + friction).min(FRICTION_MAX);
40- if self.body.friction >= FRICTION_BURN_AT
40+ if lube == Some(Lube::Lotion) {
41+ if std::mem::take(&mut self.body.conditions.friction_burn) {
42+ self.notices.push(Notice::BurnSoothed);
43+ }
44+ } else if self.body.friction >= FRICTION_BURN_AT
4145 && !self.body.conditions.friction_burn
4246 && self.chance(
4347 self.decision(
Modified file: src/tests/body.rs+21 additions
@@ -423,3 +423,24 @@ async fn stretching_reports_the_foreskin_it_grew() {
423423 }
424424 assert!(landed > 0, "forty stretches and none landed clean");
425425 }
426+
427+#[tokio::test]
428+async fn lotion_soothes_a_friction_burn() {
429+ let app = seeded_with(Floor::ChangingRoom, |run| {
430+ run.body.eq = 60;
431+ run.body.friction = 7;
432+ run.body.conditions.friction_burn = true;
433+ run.items.lubes.lotion = 1;
434+ });
435+ let soothed = send(
436+ &app,
437+ "JELQ",
438+ "/runs/cafebabe?technique=wet",
439+ &[("content-type", "application/lotion")],
440+ "",
441+ )
442+ .await;
443+ let warned = warnings(&soothed);
444+ assert!(warned.iter().any(|w| w.contains("soothed")));
445+ assert!(warned.iter().all(|w| w != "199 - \"friction burn\""));
446+}