diff --git a/src/App.vue b/src/App.vue
index 5f0a152..85f145d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -22,8 +22,7 @@ export default class App extends Vue {
   enemy: Creature
   constructor () {
     super()
-    this.player = new Creatures.Wolf()
-    this.player.perspective = POV.First
+    this.player = new Creatures.Player()
     this.enemy = new Creatures.Wolf()
     console.log(this.player)
     console.log(this.enemy)
diff --git a/src/components/Combat.vue b/src/components/Combat.vue
index 1bcf39d..bb383ad 100644
--- a/src/components/Combat.vue
+++ b/src/components/Combat.vue
@@ -5,20 +5,24 @@
     
     
     
+    
     
       
         Your moves
-        
-        
+        
+          
+          
+        
         {{actionDescription}}
        
       
         Enemy moves
-        
-        
+        
+          
+          
         
        
-    
+    
 
   
 
 
@@ -71,8 +75,20 @@ a {
   display: flex;
   justify-content: center;
 }
+.vert-display {
+  display: flex;
+  flex-direction: column;
+}
 .combat-button {
   width: 100px;
   height: 100px;
 }
 
+
+
diff --git a/src/game/combat.ts b/src/game/combat.ts
index d8a05ee..f4aaf25 100644
--- a/src/game/combat.ts
+++ b/src/game/combat.ts
@@ -1,9 +1,78 @@
-import { Creature, POV } from './entity'
-import { POVActionPicker } from './language'
+import { Creature, POV, Entity } from './entity'
+import { POVPair, POVPairArgs } from './language'
 import { Container } from './vore'
 import { LogEntry, LogLines, CompositeLog } from './interface'
 
-export enum DamageType {Pierce, Slash, Crush, Acid}
+export interface CombatTest {
+  test: (user: Creature, target: Creature) => boolean;
+  odds: (user: Creature, target: Creature) => number;
+  explain: (user: Creature, target: Creature) => LogEntry;
+}
+
+function logistic (x0: number, L: number, k: number): (x: number) => number {
+  return (x: number) => {
+    return L / (1 + Math.exp(-k * (x - x0)))
+  }
+}
+
+abstract class RandomTest implements CombatTest {
+  test (user: Creature, target: Creature): boolean {
+    return Math.random() < this.odds(user, target)
+  }
+
+  abstract odds(user: Creature, target: Creature): number
+  abstract explain(user: Creature, target: Creature): LogEntry
+}
+
+export class StatTest extends RandomTest {
+  private f: (x: number) => number
+
+  constructor (public readonly stat: Stat, k = 0.1) {
+    super()
+    this.f = logistic(0, 1, k)
+  }
+
+  odds (user: Creature, target: Creature): number {
+    return this.f(user.stats[this.stat] - target.stats[this.stat])
+  }
+
+  explain (user: Creature, target: Creature): LogEntry {
+    const delta: number = user.stats[this.stat] - target.stats[this.stat]
+    let result: string
+
+    if (delta === 0) {
+      result = 'You and the target have the same ' + this.stat + '.'
+    } else if (delta < 0) {
+      result = 'You have ' + delta + ' less ' + this.stat + ' than your foe.'
+    } else {
+      result = 'You have ' + delta + ' more ' + this.stat + ' than you foe.'
+    }
+
+    result += ' Your odds of success are ' + (100 * this.odds(user, target)) + '%'
+
+    return new LogLines(result)
+  }
+}
+
+export class ChanceTest extends RandomTest {
+  constructor (public readonly chance: number) {
+    super()
+  }
+
+  odds (user: Creature, target: Creature): number {
+    return this.chance
+  }
+
+  explain (user: Creature, target: Creature): LogEntry {
+    return new LogLines('You have a flat ' + (100 * this.chance) + '% chance.')
+  }
+}
+
+export enum DamageType {
+  Pierce = "Pierce",
+  Slash = "Slash",
+  Crush = "Crush",
+  Acid = "Acid"}
 
 export interface DamageInstance {
     type: DamageType;
@@ -11,24 +80,28 @@ export interface DamageInstance {
 }
 
 export class Damage {
-    readonly damages: DamageInstance[]
+  readonly damages: DamageInstance[]
 
-    constructor (...damages: DamageInstance[]) {
-      this.damages = damages
-    }
+  constructor (...damages: DamageInstance[]) {
+    this.damages = damages
+  }
 
-    scale (factor: number): Damage {
-      const results: Array = []
+  scale (factor: number): Damage {
+    const results: Array = []
 
-      this.damages.forEach(damage => {
-        results.push({
-          type: damage.type,
-          amount: damage.amount * factor
-        })
+    this.damages.forEach(damage => {
+      results.push({
+        type: damage.type,
+        amount: damage.amount * factor
       })
+    })
 
-      return new Damage(...results)
-    }
+    return new Damage(...results)
+  }
+
+  toString (): string {
+    return this.damages.map(damage => damage.amount + " " + damage.type).join("/")
+  }
 }
 
 export enum Stat {
@@ -83,91 +156,108 @@ abstract class TogetherAction extends PairAction {
 }
 
 export class AttackAction extends TogetherAction {
-    protected lines: POVActionPicker = {
-      [POV.First]: {
-        [POV.First]: (user, target) => new LogLines('You bite...yourself?'),
-        [POV.Third]: (user, target) => new LogLines('You bite ' + target.name)
-      },
-      [POV.Third]: {
-        [POV.First]: (user, target) => new LogLines(user.name.capital + ' bites you'),
-        [POV.Third]: (user, target) => new LogLines(user.name.capital + ' bites ' + target.name)
-      }
-    }
-
-    constructor (protected damage: Damage) {
-      super('Attack', 'Attack the enemy')
-    }
+  private test: StatTest
+
+  protected successLines: POVPairArgs = new POVPairArgs([
+    [[POV.First, POV.Third], (user, target, args) => new LogLines(`You smack ${target.name} for ${args.damage} damage`)],
+    [[POV.Third, POV.First], (user, target, args) => new LogLines(`${user.name.capital} hits you for ${args.damage} damage`)],
+    [[POV.Third, POV.Third], (user, target, args) => new LogLines(`${user.name.capital} hits ${target.name.capital} for ${args.damage} damage`)]
+  ])
+
+  protected failLines: POVPair = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You try to smack ${target.name}, but you miss`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} misses you`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} misses ${target.name}`)]
+  ])
+
+  constructor (protected damage: Damage) {
+    super('Attack', 'Attack the enemy')
+    this.test = new StatTest(Stat.STR)
+  }
 
-    execute (user: Creature, target: Creature): LogEntry {
+  execute (user: Creature, target: Creature): LogEntry {
+    if (this.test.test(user, target)) {
       target.takeDamage(this.damage)
-      return this.lines[user.perspective][target.perspective](user, target)
+      return this.successLines.run(user, target, { damage: this.damage })
+    } else {
+      return this.failLines.run(user, target)
     }
+  }
 }
 
 export class DevourAction extends TogetherAction {
-    protected lines: POVActionPicker = {
-      [POV.First]: {
-        [POV.First]: (user, target) => new LogLines('You devour...yourself?'),
-        [POV.Third]: (user, target) => new LogLines('You devour ' + target.name)
-      },
-      [POV.Third]: {
-        [POV.First]: (user, target) => new LogLines(user.name.capital + ' devours you'),
-        [POV.Third]: (user, target) => new LogLines(user.name.capital + ' devours ' + target.name)
-      }
-    }
+  private test: StatTest
 
-    constructor (protected container: Container) {
-      super('Devour', 'Try to consume your foe')
-      this.name += ` (${container.name})`
+  protected failLines: POVPair = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You fail to make a meal out of ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} tries to devour you, but fails`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} unsuccessfully tries to swallow ${target.name}`)]
+  ])
+
+  allowed (user: Creature, target: Creature): boolean {
+    const owner = this.container.owner === user
+    const predOk = Array.from(this.container.voreTypes).every(pref => user.predPrefs.has(pref))
+    const preyOk = Array.from(this.container.voreTypes).every(pref => target.preyPrefs.has(pref))
+
+    if (owner && predOk && preyOk) {
+      return super.allowed(user, target)
+    } else {
+      return false
     }
+  }
 
-    execute (user: Creature, target: Creature): LogEntry {
-      return new CompositeLog(this.lines[user.perspective][target.perspective](user, target), this.container.consume(target))
+  constructor (protected container: Container) {
+    super('Devour', 'Try to consume your foe')
+    this.name += ` (${container.name})`
+    this.test = new StatTest(Stat.STR)
+  }
+
+  execute (user: Creature, target: Creature): LogEntry {
+    if (this.test.test(user, target)) {
+      return this.container.consume(target)
+    } else {
+      return this.failLines.run(user, target)
     }
+  }
 }
 
 export class StruggleAction extends PairAction {
-    protected lines: POVActionPicker = {
-      [POV.First]: {
-        [POV.First]: (user, target) => new LogLines('You escape from...yourself?'),
-        [POV.Third]: (user, target) => new LogLines('You escape from ' + target.name)
-      },
-      [POV.Third]: {
-        [POV.First]: (user, target) => new LogLines(user.name.capital + ' escapes from you'),
-        [POV.Third]: (user, target) => new LogLines(user.name.capital + ' escapes from ' + target.name)
-      }
-    }
+  private test: StatTest
 
-    allowed (user: Creature, target: Creature) {
-      if (user.containedIn === this.container) {
-        return super.allowed(user, target)
-      } else {
-        return false
-      }
-    }
+  protected failLines: POVPair = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You fail to make a meal out of ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} tries to devour you, but fails`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name} unsuccessfully tries to swallow ${target.name}`)]
+  ])
 
-    constructor (public container: Container) {
-      super('Struggle', 'Try to escape your predator')
+  allowed (user: Creature, target: Creature) {
+    if (user.containedIn === this.container) {
+      return super.allowed(user, target)
+    } else {
+      return false
     }
+  }
 
-    execute (user: Creature, target: Creature): LogEntry {
-      if (user.containedIn) {
-        return new CompositeLog(this.lines[user.perspective][target.perspective](user, target), user.containedIn.release(user))
-      } else { return new LogLines("The prey wasn't actually eaten...") }
+  constructor (public container: Container) {
+    super('Struggle', 'Try to escape your predator')
+    this.test = new StatTest(Stat.STR)
+  }
+
+  execute (user: Creature, target: Creature): LogEntry {
+    if (user.containedIn !== null) {
+      if (this.test.test(user, target)) {
+        return user.containedIn.release(user)
+      } else {
+        return this.failLines.run(user, target)
+      }
+    } else {
+      return new LogLines("Vore's bugged!")
     }
+  }
 }
 
 export class DigestAction extends SelfAction {
-  protected lines: POVActionPicker = {
-    [POV.First]: {
-      [POV.First]: (user, target) => new LogLines('You rub your stomach'),
-      [POV.Third]: (user, target) => new LogLines("You can't digest for other people...")
-    },
-    [POV.Third]: {
-      [POV.First]: (user, target) => new LogLines("Other people can't digest for you..."),
-      [POV.Third]: (user, target) => new LogLines(user.name.capital + ' rubs ' + user.pronouns.possessive + ' gut.')
-    }
-  }
+  protected lines: POVPair = new POVPair([])
 
   allowed (user: Creature, target: Creature) {
     if (this.container.owner === user && this.container.contents.length > 0) {
@@ -184,22 +274,11 @@ export class DigestAction extends SelfAction {
 
   execute (user: Creature, target: Creature): LogEntry {
     const results = new CompositeLog(...user.containers.map(container => container.tick(60)))
-    return new CompositeLog(this.lines[user.perspective][target.perspective](user, target), results)
+    return new CompositeLog(this.lines.run(user, target), results)
   }
 }
 
 export class ReleaseAction extends PairAction {
-  protected lines: POVActionPicker = {
-    [POV.First]: {
-      [POV.First]: (user, target) => new LogLines(`You can't release yourself`),
-      [POV.Third]: (user, target) => new LogLines(`You hork up ${target.name}}`)
-    },
-    [POV.Third]: {
-      [POV.First]: (user, target) => new LogLines(`${user.name.capital} horks you up`),
-      [POV.Third]: (user, target) => new LogLines(`${user.name.capital} horks up ${target.name.capital}`)
-    }
-  }
-
   allowed (user: Creature, target: Creature) {
     if (target.containedIn === this.container) {
       return super.allowed(user, target)
@@ -214,22 +293,12 @@ export class ReleaseAction extends PairAction {
   }
 
   execute (user: Creature, target: Creature): LogEntry {
-    const results = this.container.release(target)
-    return new CompositeLog(this.lines[user.perspective][target.perspective](user, target), results)
+    return this.container.release(target)
   }
 }
 
 export class TransferAction extends PairAction {
-  protected lines: POVActionPicker = {
-    [POV.First]: {
-      [POV.First]: (user, target) => new LogLines(),
-      [POV.Third]: (user, target) => new LogLines(`You push your prey from your ${this.from.name} to your ${this.to.name}`)
-    },
-    [POV.Third]: {
-      [POV.First]: (user, target) => new LogLines(`You're shoved from ${user.name}'s ${this.from.name} to their ${this.to.name}`),
-      [POV.Third]: (user, target) => new LogLines(`${user.name.capital} pushes ${target.name} from their ${this.from.name} to their ${this.to.name}`)
-    }
-  }
+  protected lines: POVPair = new POVPair([])
 
   allowed (user: Creature, target: Creature) {
     if (target.containedIn === this.from) {
@@ -246,71 +315,6 @@ export class TransferAction extends PairAction {
   execute (user: Creature, target: Creature): LogEntry {
     this.from.release(target)
     this.to.consume(target)
-    return this.lines[user.perspective][target.perspective](user, target)
-  }
-}
-
-export interface CombatTest {
-    test: (user: Creature, target: Creature) => boolean;
-    odds: (user: Creature, target: Creature) => number;
-    explain: (user: Creature, target: Creature) => LogEntry;
-}
-
-function logistic (x0: number, L: number, k: number): (x: number) => number {
-  return (x: number) => {
-    return L / (1 + Math.exp(-k * (x - x0)))
-  }
-}
-
-abstract class RandomTest implements CombatTest {
-  test (user: Creature, target: Creature): boolean {
-    return Math.random() < this.odds(user, target)
-  }
-
-    abstract odds(user: Creature, target: Creature): number
-    abstract explain(user: Creature, target: Creature): LogEntry
-}
-
-export class StatTest extends RandomTest {
-    private f: (x: number) => number
-
-    constructor (public readonly stat: Stat, k = 0.1) {
-      super()
-      this.f = logistic(0, 1, k)
-    }
-
-    odds (user: Creature, target: Creature): number {
-      return this.f(user.stats[this.stat] - target.stats[this.stat])
-    }
-
-    explain (user: Creature, target: Creature): LogEntry {
-      const delta: number = user.stats[this.stat] - target.stats[this.stat]
-      let result: string
-
-      if (delta === 0) {
-        result = 'You and the target have the same ' + this.stat + '.'
-      } else if (delta < 0) {
-        result = 'You have ' + delta + ' less ' + this.stat + ' than your foe.'
-      } else {
-        result = 'You have ' + delta + ' more ' + this.stat + ' than you foe.'
-      }
-
-      result += ' Your odds of success are ' + (100 * this.odds(user, target)) + '%'
-
-      return new LogLines(result)
-    }
-}
-
-export class ChanceTest extends RandomTest {
-  constructor (public readonly chance: number) {
-    super()
-  }
-
-  odds (user: Creature, target: Creature): number {
-    return this.chance
-  }
-
-  explain (user: Creature, target: Creature): LogEntry {
-    return new LogLines('You have a flat ' + (100 * this.chance) + '% chance.')
+    return this.lines.run(user, target)
   }
 }
diff --git a/src/game/creatures/player.ts b/src/game/creatures/player.ts
index 369ed11..90629a8 100644
--- a/src/game/creatures/player.ts
+++ b/src/game/creatures/player.ts
@@ -1,18 +1,20 @@
 import { Creature, POV } from '../entity'
 import { ProperNoun, TheyPronouns } from '../language'
-import { Stat, Damage, AttackAction, DevourAction, DamageType } from '../combat'
-import { Stomach, VoreType } from '../vore'
+import { Stat, Damage, AttackAction, DamageType } from '../combat'
+import { Stomach, Bowels, VoreType } from '../vore'
 
 export class Player extends Creature {
   constructor () {
-    super(new ProperNoun('The Dude'), TheyPronouns, { [Stat.STR]: 20, [Stat.DEX]: 20, [Stat.CON]: 20 }, new Set([VoreType.Oral]), new Set([VoreType.Oral]), 50)
+    super(new ProperNoun('The Dude'), TheyPronouns, { [Stat.STR]: 20, [Stat.DEX]: 20, [Stat.CON]: 20 }, new Set([VoreType.Oral]), new Set([VoreType.Oral, VoreType.Anal]), 50)
+
     this.actions.push(new AttackAction(new Damage({ type: DamageType.Pierce, amount: 20 })))
 
-    const stomach = new Stomach(this, 100, new Damage({ amount: 10, type: DamageType.Acid }, { amount: 10, type: DamageType.Crush }))
+    const stomach = new Stomach(this, 100, new Damage({ amount: 100000000000, type: DamageType.Acid }, { amount: 10, type: DamageType.Crush }))
 
     this.containers.push(stomach)
-    this.actions.push(new DevourAction(stomach))
+    const bowels = new Bowels(this, 100, new Damage({ amount: 20, type: DamageType.Crush }))
 
+    this.containers.push(bowels)
     this.perspective = POV.First
   }
 }
diff --git a/src/game/creatures/wolf.ts b/src/game/creatures/wolf.ts
index e94928d..8a49f97 100644
--- a/src/game/creatures/wolf.ts
+++ b/src/game/creatures/wolf.ts
@@ -2,20 +2,16 @@ import { Creature, POV } from '../entity'
 import { Stat, Damage, DamageType, AttackAction, StruggleAction, TransferAction } from '../combat'
 import { MalePronouns, ImproperNoun } from '../language'
 import { VoreType, Stomach, Bowels } from '../vore'
-import { LogLines } from '../interface'
 
 class BiteAction extends AttackAction {
   constructor () {
     super(new Damage({ amount: 10, type: DamageType.Pierce }))
-    this.lines[POV.First][POV.Third] = (user, target) => new LogLines('You sink your fangs into ' + target.name)
-    this.lines[POV.Third][POV.First] = (user, target) => new LogLines(user.name.capital + ' bites you. This bite is easily the top 1% of bites produced by ' + user.name.plural.all + '.')
-    this.lines[POV.Third][POV.Third] = (user, target) => new LogLines(user.name.capital + ' chomps ' + target.name)
   }
 }
 
 export class Wolf extends Creature {
   constructor () {
-    super(new ImproperNoun('wolf', 'wolves'), MalePronouns, { [Stat.STR]: 10, [Stat.DEX]: 10, [Stat.CON]: 10 }, new Set([VoreType.Oral]), new Set([VoreType.Oral]), 25)
+    super(new ImproperNoun('wolf', 'wolves'), MalePronouns, { [Stat.STR]: 10, [Stat.DEX]: 10, [Stat.CON]: 10 }, new Set([VoreType.Oral, VoreType.Anal]), new Set([VoreType.Oral]), 25)
     this.actions.push(new BiteAction())
 
     const stomach = new Stomach(this, 50, new Damage({ amount: 50, type: DamageType.Acid }, { amount: 500, type: DamageType.Crush }))
diff --git a/src/game/interface.ts b/src/game/interface.ts
index c7acde8..1d9cfa6 100644
--- a/src/game/interface.ts
+++ b/src/game/interface.ts
@@ -35,9 +35,6 @@ export class CompositeLog implements LogEntry {
 
 export function log (entry: LogEntry): void {
   entry.render().forEach(elem => {
-    document.querySelector('#log')!.insertBefore(elem, document?.querySelector('#log > *'))
+    document.querySelector('#log')!.appendChild(elem)
   })
-
-  const entries: Array = Array.from(document.querySelectorAll('#log > *'))
-  entries.slice(5).forEach(element => element.remove())
 }
diff --git a/src/game/language.ts b/src/game/language.ts
index a3f9af7..35bbf39 100644
--- a/src/game/language.ts
+++ b/src/game/language.ts
@@ -1,7 +1,52 @@
-import { Creature, POV } from './entity'
-import { LogEntry } from './interface'
+import { Entity, POV } from './entity'
+import { LogEntry, LogLines } from './interface'
 
-export type POVActionPicker = { [key in POV]: { [key in POV]: (user: Creature, target: Creature) => LogEntry } }
+export class POVPair {
+  run (user: K, target: V): LogEntry {
+    const choice = this.options.find(element => element[0][0] === user.perspective && element[0][1] === target.perspective)
+
+    if (choice === undefined) {
+      return new LogLines("Fen didn't write any text for this...")
+    } else {
+      return choice[1](user, target)
+    }
+  }
+
+  constructor (private options: Array<[[POV, POV], (user: K, target: V) => LogEntry]>) {
+
+  }
+}
+
+export class POVPairArgs {
+  run (user: K, target: V, args: U): LogEntry {
+    const choice = this.options.find(element => element[0][0] === user.perspective && element[0][1] === target.perspective)
+
+    if (choice === undefined) {
+      return new LogLines("Fen didn't write any text for this...")
+    } else {
+      return choice[1](user, target, args)
+    }
+  }
+
+  constructor (private options: Array<[[POV, POV], (user: K, target: V, args: U) => LogEntry]>) {
+
+  }
+}
+export class POVSolo {
+  run (user: K, args: any = {}): LogEntry {
+    const choice = this.options.find(element => element[0][0] === user.perspective)
+
+    if (choice === undefined) {
+      return new LogLines("Fen didn't write any text for this...")
+    } else {
+      return choice[1](user, args)
+    }
+  }
+
+  constructor (private options: Array<[[POV], (user: K, args: any) => LogEntry]>) {
+
+  }
+}
 
 enum NounKind {
     Specific,
diff --git a/src/game/vore.ts b/src/game/vore.ts
index 3aa34c3..1be3735 100644
--- a/src/game/vore.ts
+++ b/src/game/vore.ts
@@ -1,7 +1,14 @@
 import { Entity, Mortal, POV } from './entity'
 import { Damage, Actionable, Action, DevourAction, DigestAction, ReleaseAction, StruggleAction } from './combat'
 import { LogLines, LogEntry, CompositeLog } from './interface'
-export enum VoreType {Oral}
+import { POVSolo, POVPair, POVPairArgs } from './language'
+
+export enum VoreType {
+  Oral = "Oral Vore",
+  Anal = "Anal Vore",
+  Cock = "Cock Vore",
+  Unbirth = "Unbirthing"
+}
 
 export interface Prey extends Mortal {
     preyPrefs: Set;
@@ -36,6 +43,14 @@ export interface Container extends Actionable {
 abstract class NormalContainer implements Container {
     contents: Array
 
+    abstract consumeLines: POVPair
+    abstract releaseLines: POVPair
+    abstract struggleLines: POVPair
+    abstract tickLines: POVSolo
+    abstract digestLines: POVPair
+    abstract absorbLines: POVPair
+    abstract disposeLines: POVPair
+
     get fullness (): number {
       return Array.from(this.contents.values()).reduce((total: number, prey: Prey) => total + prey.bulk, 0)
     }
@@ -53,17 +68,17 @@ abstract class NormalContainer implements Container {
     consume (prey: Prey): LogEntry {
       this.contents.push(prey)
       prey.containedIn = this
-      return new LogLines('MUNCH')
+      return this.consumeLines.run(this.owner, prey)
     }
 
     release (prey: Prey): LogEntry {
       prey.containedIn = null
       this.contents = this.contents.filter(victim => victim !== prey)
-      return new LogLines('ANTI-MUNCH')
+      return this.releaseLines.run(this.owner, prey)
     }
 
     struggle (prey: Prey): LogEntry {
-      return new LogLines('Slosh!')
+      return this.struggleLines.run(prey, this.owner)
     }
 
     tick (dt: number): LogEntry {
@@ -88,7 +103,7 @@ abstract class NormalContainer implements Container {
         return prey.health > -100
       })
 
-      return new CompositeLog(digestedEntries, absorbedEntries)
+      return new CompositeLog(this.tickLines.run(this.owner), digestedEntries, absorbedEntries)
     }
 
     describe (): LogEntry {
@@ -102,15 +117,15 @@ abstract class NormalContainer implements Container {
     }
 
     digest (prey: Prey): LogEntry {
-      return new LogLines('Glorp!')
+      return this.digestLines.run(this.owner, prey)
     }
 
     absorb (prey: Prey): LogEntry {
-      return new LogLines('Glorp...')
+      return this.absorbLines.run(this.owner, prey)
     }
 
     dispose (preys: Prey[]): LogEntry {
-      return new LogLines('GLORP')
+      return new CompositeLog(...preys.map(prey => this.disposeLines.run(this.owner, prey)))
     }
 
     actions: Array
@@ -119,127 +134,104 @@ abstract class NormalContainer implements Container {
       this.contents = []
 
       this.actions = []
+
+      this.actions.push(new DevourAction(this))
+      this.actions.push(new DigestAction(this))
+      this.actions.push(new ReleaseAction(this))
+      this.actions.push(new StruggleAction(this))
     }
 }
 
 export class Stomach extends NormalContainer {
   constructor (owner: Pred, capacity: number, damage: Damage) {
     super('Stomach', owner, new Set([VoreType.Oral]), capacity, damage)
-
-    this.actions.push(new DevourAction(this))
-    this.actions.push(new DigestAction(this))
-    this.actions.push(new ReleaseAction(this))
-    this.actions.push(new StruggleAction(this))
-  }
-
-  consume (prey: Prey): LogEntry {
-    super.consume(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines(prey.name.capital + ' slides down into your stomach')
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + "'s guts swell as you slush down into " + this.owner.pronouns.possessive + ' stomach')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + "'s belly fills with the struggling form of " + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
   }
 
-  digest (prey: Prey): LogEntry {
-    super.digest(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines('Your stomach finishes off ' + prey.name)
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + ' digests you')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + ' finishes digesting ' + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
-  }
-
-  absorb (prey: Prey): LogEntry {
-    super.absorb(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines("Your stomach melts down what's left of " + prey.name)
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + ' finishes absorbing you')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + ' fully absorbs ' + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
-  }
+  consumeLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} munches you`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)]
+  ])
+
+  releaseLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You hork up ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} horks you up`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} horks up ${target.name.capital}`)]
+  ])
+
+  struggleLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You claw your way out of ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} forces ${user.pronouns.possessive} way up your throat!`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} escapes from the gut of ${target.name}`)]
+  ])
+
+  tickLines = new POVSolo([
+    [[POV.First], (user) => new LogLines(`Your stomach gurgles and churns`)],
+    [[POV.Third], (user) => new LogLines(`${user.name.capital}'s gut snarls and gurgles`)]
+  ])
+
+  digestLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your stomach overwhelms ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s stomach finishes you off`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name.capital}'s squirms fade, overwhelmed by the stomach of ${user.name}`)]
+  ])
+
+  absorbLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
+  ])
+
+  disposeLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
+  ])
 }
 
 export class Bowels extends NormalContainer {
   constructor (owner: Pred, capacity: number, damage: Damage) {
-    super('Bowels', owner, new Set([VoreType.Oral]), capacity, damage)
-
-    this.actions.push(new DevourAction(this))
-    this.actions.push(new DigestAction(this))
-    this.actions.push(new ReleaseAction(this))
-    this.actions.push(new StruggleAction(this))
-  }
-
-  consume (prey: Prey): LogEntry {
-    super.consume(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines(prey.name.capital + ' slides down into your bowels')
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + "'s guts swell as you slush down into " + this.owner.pronouns.possessive + ' bowels')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + "'s belly fills with the struggling form of " + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
+    super('Bowels', owner, new Set([VoreType.Anal]), capacity, damage)
   }
 
-  digest (prey: Prey): LogEntry {
-    super.digest(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines('Your bowels finishes off ' + prey.name)
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + ' digests you')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + ' finishes digesting ' + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
-  }
-
-  absorb (prey: Prey): LogEntry {
-    super.absorb(prey)
-
-    const predPOV = this.owner.perspective
-    const preyPOV = prey.perspective
-
-    if (predPOV === POV.First && preyPOV === POV.Third) {
-      return new LogLines("Your bowels melts down what's left of " + prey.name)
-    } else if (predPOV === POV.Third && preyPOV === POV.First) {
-      return new LogLines(this.owner.name.capital + ' finishes absorbing you')
-    } else if (predPOV === POV.Third && preyPOV === POV.Third) {
-      return new LogLines(this.owner.name.capital + ' fully absorbs ' + prey.name)
-    } else {
-      return new LogLines('FIX ME!')
-    }
-  }
+  consumeLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You devour ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} munches you`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} munches ${target.name.capital}`)]
+  ])
+
+  releaseLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You hork up ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} horks you up`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} horks up ${target.name.capital}`)]
+  ])
+
+  struggleLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`You claw your way out of ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital} forces ${user.pronouns.possessive} way up your throat!`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} escapes from the gut of ${target.name}`)]
+  ])
+
+  tickLines = new POVSolo([
+    [[POV.First], (user) => new LogLines(`Your stomach gurgles and churns!`)],
+    [[POV.Third], (user) => new LogLines(`${user.name.capital}'s gut snarls and gurgles`)]
+  ])
+
+  digestLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your stomach overwhelms ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s stomach finishes you off`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${target.name.capital}'s squirms fade, overwhelmed by the stomach of ${user.name}`)]
+  ])
+
+  absorbLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
+  ])
+
+  disposeLines = new POVPair([
+    [[POV.First, POV.Third], (user, target) => new LogLines(`Your guts completely absorb ${target.name}`)],
+    [[POV.Third, POV.First], (user, target) => new LogLines(`${user.name.capital}'s guts soak you up like water in a sponge`)],
+    [[POV.Third, POV.Third], (user, target) => new LogLines(`${user.name.capital} finishes absorbing the remains of ${target.name}`)]
+  ])
 }