diff --git a/src/components/ActionButton.vue b/src/components/ActionButton.vue
index 541e2a2..bd1eeac 100644
--- a/src/components/ActionButton.vue
+++ b/src/components/ActionButton.vue
@@ -1,5 +1,5 @@
 
-  
 
@@ -91,6 +93,20 @@ export default class Combat extends Vue {
       log.scrollTo({ top: 10000000000, left: 0 })
     }
   }
+
+  @Emit("described")
+  described (entry: LogEntry) {
+    const actionDesc = document.querySelector("#action-desc")
+
+    if (actionDesc !== null) {
+      const holder = document.createElement("div")
+      entry.render().forEach(element => {
+        holder.appendChild(element)
+      })
+      actionDesc.innerHTML = ''
+      actionDesc.appendChild(holder)
+    }
+  }
 }
 
 
@@ -115,7 +131,7 @@ export default class Combat extends Vue {
 
 #log {
   grid-area: main-row-start / main-col-start / main-row-end / main-col-end;
-  overflow-y: auto;
+  overflow-y: scroll;
   font-size: 16pt;
   width: 100%;
   max-height: 100%;
@@ -138,6 +154,10 @@ export default class Combat extends Vue {
   grid-area: 4 / 3 / 6 / 4;
 }
 
+#action-desc {
+  grid-area: main-row-end / main-col-start / 6 / main-col-end
+}
+
 h3 {
   margin: 40px 0 0;
 }
diff --git a/src/game/combat.ts b/src/game/combat.ts
index 743f7ec..5462881 100644
--- a/src/game/combat.ts
+++ b/src/game/combat.ts
@@ -25,15 +25,15 @@ export enum Vigor {
 }
 
 export const VigorIcons: {[key in Vigor]: string} = {
-  [Vigor.Health]: "fas fa-heart",
-  [Vigor.Stamina]: "fas fa-bolt",
-  [Vigor.Resolve]: "fas fa-brain"
+  Health: "fas fa-heart",
+  Stamina: "fas fa-bolt",
+  Resolve: "fas fa-brain"
 }
 
 export const VigorDescs: {[key in Vigor]: string} = {
-  [Vigor.Health]: "How much damage you can take",
-  [Vigor.Stamina]: "How much energy you have",
-  [Vigor.Resolve]: "How much dominance you can resist"
+  Health: "How much damage you can take",
+  Stamina: "How much energy you have",
+  Resolve: "How much dominance you can resist"
 }
 
 export type Vigors = {[key in Vigor]: number}
@@ -49,19 +49,19 @@ export enum Stat {
 export type Stats = {[key in Stat]: number}
 
 export const StatIcons: {[key in Stat]: string} = {
-  [Stat.Toughness]: 'fas fa-heartbeat',
-  [Stat.Power]: 'fas fa-fist-raised',
-  [Stat.Speed]: 'fas fa-feather',
-  [Stat.Willpower]: 'fas fa-book',
-  [Stat.Charm]: 'fas fa-comments'
+  Toughness: 'fas fa-heartbeat',
+  Power: 'fas fa-fist-raised',
+  Speed: 'fas fa-feather',
+  Willpower: 'fas fa-book',
+  Charm: 'fas fa-comments'
 }
 
 export const StatDescs: {[key in Stat]: string} = {
-  [Stat.Toughness]: 'Your physical resistance',
-  [Stat.Power]: 'Your physical power',
-  [Stat.Speed]: 'How quickly you can act',
-  [Stat.Willpower]: 'Your mental resistance',
-  [Stat.Charm]: 'Your mental power'
+  Toughness: 'Your physical resistance',
+  Power: 'Your physical power',
+  Speed: 'How quickly you can act',
+  Willpower: 'Your mental resistance',
+  Charm: 'Your mental power'
 }
 
 export interface CombatTest {
@@ -129,7 +129,7 @@ export class StatVigorTest extends RandomTest {
       result = 'You have ' + delta + ' more ' + this.stat + ' than you foe.'
     }
 
-    result += ' Your odds of success are ' + (100 * this.odds(user, target)) + '%'
+    result += ' Your odds of success are ' + (100 * this.odds(user, target)).toFixed(1) + '%'
 
     return new LogLines(result)
   }
@@ -159,7 +159,7 @@ export class StatTest extends RandomTest {
       result = 'You have ' + delta + ' more ' + this.stat + ' than you foe.'
     }
 
-    result += ' Your odds of success are ' + (100 * this.odds(user, target)) + '%'
+    result += ' Your odds of success are ' + (100 * this.odds(user, target)).toFixed(1) + '%'
 
     return new LogLines(result)
   }
@@ -221,6 +221,39 @@ export class Damage {
   }
 }
 
+export interface DamageFormula {
+  calc (user: Creature, target: Creature): Damage;
+  describe (user: Creature, target: Creature): LogEntry;
+}
+
+export class ConstantDamageFormula implements DamageFormula {
+  calc (user: Creature, target: Creature): Damage {
+    return this.damage
+  }
+
+  constructor (private damage: Damage) {
+
+  }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine('Deal ', this.damage.renderShort(), ' damage')
+  }
+}
+
+export class UniformRandomDamageFormula implements DamageFormula {
+  calc (user: Creature, target: Creature): Damage {
+    return this.damage.scale(Math.random() * this.variance * 2 - this.variance + 1)
+  }
+
+  constructor (private damage: Damage, private variance: number) {
+
+  }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine('Deal between ', this.damage.scale(1 - this.variance).renderShort(), ' and ', this.damage.scale(1 + this.variance).renderShort(), ' damage.')
+  }
+}
+
 export interface Combatant {
     actions: Array;
 }
@@ -232,7 +265,9 @@ export abstract class Action {
 
   abstract execute(user: Creature, target: Creature): LogEntry
 
-  constructor (public name: TextLike, public desc: string, private conditions: Array = []) {
+  abstract describe (user: Creature, target: Creature): LogEntry
+
+  constructor (public name: TextLike, public desc: TextLike, private conditions: Array = []) {
 
   }
 
@@ -328,20 +363,25 @@ export class AttackAction extends TogetherAction {
     [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} misses ${target.name}`)]
   ])
 
-  constructor (protected damage: Damage) {
+  constructor (protected damage: DamageFormula) {
     super('Attack', 'Attack the enemy', [new CapableCondition()])
     this.test = new StatTest(Stat.Power)
   }
 
   execute (user: Creature, target: Creature): LogEntry {
     if (this.test.test(user, target)) {
-      const targetResult = target.takeDamage(this.damage)
-      const ownResult = this.successLines.run(user, target, { damage: this.damage })
+      const damage = this.damage.calc(user, target)
+      const targetResult = target.takeDamage(damage)
+      const ownResult = this.successLines.run(user, target, { damage: damage })
       return new CompositeLog(ownResult, targetResult)
     } else {
       return this.failLines.run(user, target)
     }
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Attack ${target.name}. `, this.damage.describe(user, target), '. ', this.test.explain(user, target))
+  }
 }
 
 export class DevourAction extends TogetherAction {
@@ -377,6 +417,10 @@ export class DevourAction extends TogetherAction {
       return this.failLines.run(user, target)
     }
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Try to consume your opponent, sending them to your ${this.container.name}. `, this.test.explain(user, target))
+  }
 }
 
 export class FeedAction extends TogetherAction {
@@ -409,6 +453,10 @@ export class FeedAction extends TogetherAction {
   execute (user: Creature, target: Creature): LogEntry {
     return this.container.consume(user)
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Your willpower is drained, and you really feel like shoving yourself into ${target.name}'s ${this.container.name}...`)
+  }
 }
 
 export class StruggleAction extends PairAction {
@@ -444,6 +492,10 @@ export class StruggleAction extends PairAction {
       return new LogLines("Vore's bugged!")
     }
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Try to escape from ${target.name}'s ${this.container.name}. `, this.test.explain(user, target))
+  }
 }
 
 export abstract class EatenAction extends PairAction {
@@ -458,7 +510,7 @@ export abstract class EatenAction extends PairAction {
   }
 
   constructor (public container: Container, name: TextLike, desc: string) {
-    super(new DynText(name, ' (', new LiveText(container, x => x.name.all), ')'), 'Do something to your prey!', [new CapableCondition()])
+    super(new DynText(name, ' (', new LiveText(container, x => x.name.all), ')'), desc, [new CapableCondition()])
   }
 }
 export class DigestAction extends SelfAction {
@@ -480,6 +532,10 @@ export class DigestAction extends SelfAction {
     const results = this.container.tick(60)
     return new CompositeLog(results)
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Digest everyone inside of your ${this.container.name}.`)
+  }
 }
 
 export class ReleaseAction extends PairAction {
@@ -498,6 +554,10 @@ export class ReleaseAction extends PairAction {
   execute (user: Creature, target: Creature): LogEntry {
     return this.container.release(target)
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Release ${target.name} from your ${this.container.name}.`)
+  }
 }
 
 export class TransferAction extends PairAction {
@@ -516,7 +576,7 @@ export class TransferAction extends PairAction {
   }
 
   constructor (protected from: Container, protected to: Container) {
-    super('Transfer', `Shove your prey from your ${from.name} to your ${to.name}`, [new CapableCondition()])
+    super('Transfer', `Move from your ${from.name} to your ${to.name}`, [new CapableCondition()])
   }
 
   execute (user: Creature, target: Creature): LogEntry {
@@ -524,4 +584,8 @@ export class TransferAction extends PairAction {
     this.to.consume(target)
     return this.lines.run(user, target, { from: this.from, to: this.to })
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Push ${target.name} from your ${this.from.name} to your ${this.to.name}`)
+  }
 }
diff --git a/src/game/creatures/cafat.ts b/src/game/creatures/cafat.ts
index b72a6c5..a083f28 100644
--- a/src/game/creatures/cafat.ts
+++ b/src/game/creatures/cafat.ts
@@ -1,5 +1,5 @@
 import { Creature, POV, Entity } from '../entity'
-import { Stat, Damage, DamageType, TransferAction, Vigor, StatTest, FeedAction, DigestAction, EatenAction, AttackAction } from '../combat'
+import { Stat, Damage, DamageType, TransferAction, Vigor, StatTest, FeedAction, DigestAction, EatenAction, AttackAction, DamageFormula, ConstantDamageFormula } from '../combat'
 import { ProperNoun, TheyPronouns, ImproperNoun, POVPair, FemalePronouns, POVPairArgs } from '../language'
 import { VoreType, Stomach, InnerStomach, Container, Bowels } from '../vore'
 import { LogLine, LogLines, LogEntry, FAElem, CompositeLog, ImgElem } from '../interface'
@@ -21,15 +21,17 @@ class BellyCrushAction extends AttackAction {
     ), new ImgElem('./media/cafat/images/belly-crush.webp'))]
   ])
 
-  constructor (private _damage: Damage) {
-    super(_damage)
+  constructor (_damage: Damage) {
+    super({
+      calc (user, target) { return _damage.scale(user.bulk / 25) },
+      describe (user, target) { return new LogLine('Deal ', _damage.scale(user.bulk / 25).renderShort(), ` with your ${user.bulk} `, new FAElem('fas fa-weight-hanging')) }
+    })
     this.name = 'Belly Crush'
-    this.desc = 'Deal damage proportional to your bulk'
+    this.desc = 'Use your weight!'
   }
 
-  execute (user: Creature, target: Creature): LogEntry {
-    this.damage = this._damage.scale(user.bulk / 25 + 1)
-    return super.execute(user, target)
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Crush ${target.name} under your gut. `, this.damage.describe(user, target))
   }
 }
 
@@ -50,7 +52,7 @@ class BelchAction extends AttackAction {
   ])
 
   constructor (damage: Damage) {
-    super(damage)
+    super(new ConstantDamageFormula(damage))
     this.name = 'Belch'
     this.desc = 'Drain your foe\'s willpower with a solid BELCH'
   }
@@ -75,6 +77,10 @@ class CrushAction extends EatenAction {
     target.takeDamage(this.damage)
     return this.lines.run(user, target)
   }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine(`Crush ${target.name} in your ${this.container.name} for massive, unavoidable damage.`)
+  }
 }
 
 export class Cafat extends Creature {
@@ -132,7 +138,7 @@ export class Cafat extends Creature {
     this.actions.push(transfer)
     this.actions.push(new TransferAction(lowerStomach, stomach))
 
-    this.actions.push(new AttackAction(new Damage({ amount: 40, type: DamageType.Crush, target: Vigor.Health })))
+    this.actions.push(new AttackAction(new ConstantDamageFormula(new Damage({ amount: 40, type: DamageType.Crush, target: Vigor.Health }))))
     this.actions.push(new BellyCrushAction(new Damage({ amount: 10, type: DamageType.Crush, target: Vigor.Health }, { amount: 10, type: DamageType.Dominance, target: Vigor.Resolve })))
     this.actions.push(new BelchAction(new Damage(
       { amount: 100, target: Vigor.Resolve, type: DamageType.Acid }
diff --git a/src/game/creatures/player.ts b/src/game/creatures/player.ts
index da25d80..ef95e79 100644
--- a/src/game/creatures/player.ts
+++ b/src/game/creatures/player.ts
@@ -1,13 +1,13 @@
 import { Creature, POV } from '../entity'
 import { ProperNoun, TheyPronouns } from '../language'
-import { Stat, Damage, AttackAction, DamageType, Vigor } from '../combat'
+import { Stat, Damage, AttackAction, DamageType, Vigor, ConstantDamageFormula } from '../combat'
 import { Stomach, Bowels, VoreType } from '../vore'
 
 export class Player extends Creature {
   constructor () {
     super(new ProperNoun('The Dude'), TheyPronouns, { Toughness: 20, Power: 20, Speed: 20, Willpower: 20, Charm: 20 }, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral, VoreType.Anal]), 50)
 
-    this.actions.push(new AttackAction(new Damage({ type: DamageType.Pierce, amount: 20, target: Vigor.Health }, { type: DamageType.Pierce, amount: 20, target: Vigor.Stamina })))
+    this.actions.push(new AttackAction(new ConstantDamageFormula(new Damage({ type: DamageType.Pierce, amount: 20, target: Vigor.Health }, { type: DamageType.Pierce, amount: 20, target: Vigor.Stamina }))))
 
     const stomach = new Stomach(this, 100, new Damage({ amount: 20, type: DamageType.Acid, target: Vigor.Health }, { amount: 10, type: DamageType.Crush, target: Vigor.Health }))
 
diff --git a/src/game/creatures/wolf.ts b/src/game/creatures/wolf.ts
index b9fae97..54a10ae 100644
--- a/src/game/creatures/wolf.ts
+++ b/src/game/creatures/wolf.ts
@@ -1,12 +1,12 @@
 import { Creature, POV, Entity } from '../entity'
-import { Stat, Damage, DamageType, AttackAction, TransferAction, Vigor, StatTest, FeedAction } from '../combat'
+import { Stat, Damage, DamageType, AttackAction, TransferAction, Vigor, StatTest, FeedAction, ConstantDamageFormula } from '../combat'
 import { MalePronouns, ImproperNoun, POVPair, POVPairArgs } from '../language'
 import { LogLine, LogLines } from '../interface'
 import { VoreType, Stomach, Bowels } from '../vore'
 
 class BiteAction extends AttackAction {
   constructor () {
-    super(new Damage({ amount: 10, type: DamageType.Slash, target: Vigor.Health }))
+    super(new ConstantDamageFormula(new Damage({ amount: 10, type: DamageType.Slash, target: Vigor.Health })))
     this.name = "Bite"
   }
 }
@@ -34,7 +34,7 @@ class HypnoAction extends AttackAction {
   ])
 
   constructor () {
-    super(new Damage({ amount: 30, type: DamageType.Dominance, target: Vigor.Resolve }))
+    super(new ConstantDamageFormula(new Damage({ amount: 30, type: DamageType.Dominance, target: Vigor.Resolve })))
     this.test = new StatTest(Stat.Willpower)
     this.name = "Hypnotize"
   }
diff --git a/src/game/interface.ts b/src/game/interface.ts
index ceee324..86a083c 100644
--- a/src/game/interface.ts
+++ b/src/game/interface.ts
@@ -1,3 +1,5 @@
+import { Stat, Vigor } from './combat'
+
 export interface LogEntry {
   render: () => HTMLElement[];
 }
@@ -62,7 +64,7 @@ export class LogLine implements LogEntry {
   }
 
   render (): HTMLElement[] {
-    const div = document.createElement("div")
+    const div = document.createElement("span")
 
     this.parts.forEach(part => {
       if (typeof part === "string") {
@@ -92,6 +94,37 @@ export class FAElem implements LogEntry {
   }
 }
 
+export class PropElem implements LogEntry {
+  constructor (private value: number, private prop: Stat | Vigor) {
+
+  }
+
+  render (): HTMLElement[] {
+    let cls: string
+    switch (this.prop) {
+      case Vigor.Health: cls = "fas fa-heart"; break
+      case Vigor.Stamina: cls = "fas fa-bolt"; break
+      case Vigor.Resolve: cls = "fas fa-brain"; break
+      case Stat.Toughness: cls = "fas fa-heartbeat"; break
+      case Stat.Power: cls = "fas fa-fist-raised"; break
+      case Stat.Speed: cls = "fas fa-weather"; break
+      case Stat.Willpower: cls = "fas fa-book"; break
+      case Stat.Charm: cls = "fas fa-comments"; break
+    }
+
+    const span = document.createElement("span")
+    span.classList.add("stat-entry")
+    span.textContent = this.value.toString()
+    new FAElem(cls).render().forEach(elem => {
+      span.appendChild(elem)
+    })
+    span.dataset.tooltip = this.prop
+    span.dataset["tooltip-full"] = this.prop
+
+    return [span]
+  }
+}
+
 export class ImgElem implements LogEntry {
   constructor (private url: string) {