@@ -47,7 +48,7 @@ import { POV } from '@/game/language'
 import { LogEntry } from '@/game/interface'
 import Statblock from './Statblock.vue'
 import ActionButton from './ActionButton.vue'
-import { Side } from '@/game/combat'
+import { Side, Encounter } from '@/game/combat'
 
 @Component(
   {
@@ -55,7 +56,8 @@ import { Side } from '@/game/combat'
     data () {
       return {
         left: null,
-        right: null
+        right: null,
+        combatants: null
       }
     },
     methods: {
@@ -72,6 +74,16 @@ import { Side } from '@/game/combat'
         if (target !== null) {
           target.scrollBy({ top: 0, left: event.deltaY, behavior: 'smooth' })
         }
+      },
+      doSelectLeft (combatant: Creature) {
+        if (combatant.side !== this.$props.encounter.currentMove.side) {
+          this.$data.left = combatant
+        }
+      },
+      doSelectRight (combatant: Creature) {
+        if (combatant.side !== this.$props.encounter.currentMove.side) {
+          this.$data.right = combatant
+        }
       }
     }
   }
@@ -79,15 +91,16 @@ import { Side } from '@/game/combat'
 
 export default class Combat extends Vue {
   @Prop()
-  combatants!: Array
+  encounter!: Encounter
 
   Side = Side
 
   actionDescription = ''
 
   created () {
-    this.$data.left = this.combatants.filter(x => x.side === Side.Heroes)[0]
-    this.$data.right = this.combatants.filter(x => x.side === Side.Monsters)[0]
+    this.$data.left = this.encounter.combatants.filter(x => x.side === Side.Heroes)[0]
+    this.$data.right = this.encounter.combatants.filter(x => x.side === Side.Monsters)[0]
+    this.$data.combatants = this.encounter.combatants
   }
 
   mounted () {
@@ -112,6 +125,23 @@ export default class Combat extends Vue {
 
       log.scrollTo({ top: log.scrollHeight, left: 0 })
     }
+
+    this.encounter.nextMove()
+
+    if (this.encounter.currentMove.side === Side.Heroes) {
+      this.$data.left = this.encounter.currentMove
+      this.$el.querySelector("#left-stats ")
+    } else if (this.encounter.currentMove.side === Side.Monsters) {
+      this.$data.right = this.encounter.currentMove
+    }
+
+    // scroll to the newly selected creature
+    this.$nextTick(() => {
+      const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]")
+      if (creature !== null) {
+        creature.scrollIntoView()
+      }
+    })
   }
 
   @Emit("executedRight")
@@ -128,6 +158,22 @@ export default class Combat extends Vue {
 
       log.scrollTo({ top: log.scrollHeight, left: 0 })
     }
+
+    this.encounter.nextMove()
+
+    if (this.encounter.currentMove.side === Side.Heroes) {
+      this.$data.left = this.encounter.currentMove
+    } else if (this.encounter.currentMove.side === Side.Monsters) {
+      this.$data.right = this.encounter.currentMove
+    }
+
+    // scroll to the newly selected creature
+    this.$nextTick(() => {
+      const creature: HTMLElement|null = this.$el.querySelector("[data-current-turn]")
+      if (creature !== null) {
+        creature.scrollIntoView()
+      }
+    })
   }
 
   @Emit("described")
diff --git a/src/components/Statblock.vue b/src/components/Statblock.vue
index 44a2995..2798e02 100644
--- a/src/components/Statblock.vue
+++ b/src/components/Statblock.vue
@@ -3,6 +3,7 @@
     
     
     
+    
     
     
     
@@ -13,6 +14,7 @@
           
{{ subject.desc }}
          Initiative: {{ (initiative).toFixed(0) }}%
       
         
           {{ status.topLeft }}
@@ -105,6 +107,9 @@ export default class Statblock extends Vue {
   @Prop({ type: Creature, required: true })
   subject!: Creature
 
+  @Prop()
+  initiative!: number
+
   private vigorIcons = VigorIcons
   private statIcons = StatIcons
   private voreStatIcons = VoreStatIcons
@@ -283,6 +288,15 @@ a {
   opacity: 0.20;
 }
 
+.statblock[data-current-turn] .statblock-shader-current-turn {
+  background: #0f0;
+  opacity: 0.3;
+}
+
+.statblock[data-disabled] {
+  color: #888;
+}
+
 .statblock[data-dead] .statblock-shader-dead {
   background: red;
   opacity: 0.50;
diff --git a/src/game/combat.ts b/src/game/combat.ts
index 71272a7..f98ffbe 100644
--- a/src/game/combat.ts
+++ b/src/game/combat.ts
@@ -320,6 +320,34 @@ export abstract class GroupAction extends Action {
   }
 }
 
+/**
+ * Individual status effects, items, etc. should override some of these hooks.
+ * Some hooks just produce a log entry.
+ * Some hooks return results along with a log entry.
+ */
+export class Effective {
+  onApply (creature: Creature): LogEntry { return nilLog }
+
+  onRemove (creature: Creature): LogEntry { return nilLog }
+
+  preAction (creature: Creature): { prevented: boolean; log: LogEntry } {
+    return {
+      prevented: false,
+      log: nilLog
+    }
+  }
+
+  preDamage (creature: Creature, damage: Damage): Damage {
+    return damage
+  }
+
+  preAttack (creature: Creature, attacker: Creature): { prevented: boolean; log: LogEntry } {
+    return {
+      prevented: false,
+      log: nilLog
+    }
+  }
+}
 /**
  * A displayable status effect
  */
@@ -346,38 +374,64 @@ export class ImplicitStatus implements VisibleStatus {
 
 /**
  * This kind of status is explicitly given to a creature.
- *
- * Individual status effects should override some of its hooks.
- * Some hooks just produce a log entry.
- * Some hooks return results along with a log entry.
  */
-export abstract class StatusEffect implements VisibleStatus {
+export abstract class StatusEffect extends Effective implements VisibleStatus {
   constructor (public name: TextLike, public desc: TextLike, public icon: string) {
-
+    super()
   }
 
   get topLeft () { return '' }
   get bottomRight () { return '' }
+}
 
-  onApply (creature: Creature): LogEntry { return nilLog }
+/**
+ * An Encounter describes a fight: who is in it and whose turn it is
+ */
+export class Encounter {
+  private initiatives: Map
+  currentMove: Creature
+  turnTime = 100
 
-  onRemove (creature: Creature): LogEntry { return nilLog }
+  constructor (public combatants: Creature[]) {
+    this.initiatives = new Map()
 
-  preAction (creature: Creature): { prevented: boolean; log: LogEntry } {
-    return {
-      prevented: false,
-      log: nilLog
-    }
-  }
+    combatants.forEach(combatant => this.initiatives.set(combatant, 0))
+    this.currentMove = combatants[0]
 
-  preDamage (creature: Creature, damage: Damage): Damage {
-    return damage
+    this.nextMove()
   }
 
-  preAttack (creature: Creature, attacker: Creature): { prevented: boolean; log: LogEntry } {
-    return {
-      prevented: false,
-      log: nilLog
+  nextMove (): void {
+    this.initiatives.set(this.currentMove, 0)
+    const times = new Map()
+
+    this.combatants.forEach(combatant => {
+      // this should never be undefined
+      const currentProgress = this.initiatives.get(combatant) ?? 0
+      const remaining = (this.turnTime - currentProgress) / Math.max(combatant.stats.Speed, 1)
+      times.set(combatant, remaining)
+    })
+
+    this.currentMove = this.combatants.reduce((closest, next) => {
+      const closestTime = times.get(closest) ?? 0
+      const nextTime = times.get(next) ?? 0
+
+      return closestTime <= nextTime ? closest : next
+    }, this.combatants[0])
+    const closestRemaining = (this.turnTime - (this.initiatives.get(this.currentMove) ?? 0)) / Math.max(this.currentMove.stats.Speed, 1)
+
+    this.combatants.forEach(combatant => {
+      // still not undefined...
+      const currentProgress = this.initiatives.get(combatant) ?? 0
+      this.initiatives.set(combatant, currentProgress + closestRemaining * Math.max(combatant.stats.Speed, 1))
+      console.log(combatant.name.toString(), currentProgress, closestRemaining)
+    })
+
+    // TODO: still let the creature use drained-vigor moves
+
+    console.log(this.currentMove.name.toString())
+    if (this.currentMove.disabled) {
+      this.nextMove()
     }
   }
 }
diff --git a/src/game/combat/actions.ts b/src/game/combat/actions.ts
index f342a63..ed734e7 100644
--- a/src/game/combat/actions.ts
+++ b/src/game/combat/actions.ts
@@ -2,10 +2,24 @@ import { StatTest, StatVigorTest } from './tests'
 import { DynText, LiveText, TextLike, Verb, PairLine, PairLineArgs } from '../language'
 import { Entity, Creature } from '../entity'
 import { Damage, DamageFormula, Stat, Vigor, Action } from '../combat'
-import { LogLine, LogLines, LogEntry, CompositeLog } from '../interface'
+import { LogLine, LogLines, LogEntry, CompositeLog, nilLog } from '../interface'
 import { VoreContainer, Container } from '../vore'
 import { CapableCondition, UserDrainedVigorCondition, TogetherCondition, EnemyCondition, SoloCondition, PairCondition, ContainsCondition, ContainedByCondition } from './conditions'
 
+export class PassAction extends Action {
+  execute (user: Creature, target: Creature): LogEntry {
+    return nilLog
+  }
+
+  describe (user: Creature, target: Creature): LogEntry {
+    return new LogLine("Do nothing.")
+  }
+
+  constructor () {
+    super("Pass", "Do nothing", [new SoloCondition()])
+  }
+}
+
 export class AttackAction extends Action {
   protected test: StatTest
 
diff --git a/src/game/entity.ts b/src/game/entity.ts
index 7a00841..0a359f6 100644
--- a/src/game/entity.ts
+++ b/src/game/entity.ts
@@ -3,6 +3,7 @@ import { Noun, Pronoun, TextLike, POV } from './language'
 import { LogEntry, LogLine, LogLines } from './interface'
 import { Vore, VoreContainer, VoreType, Container } from './vore'
 import { Item } from './items'
+import { PassAction } from './combat/actions'
 
 export interface Entity {
     name: Noun;
@@ -94,6 +95,7 @@ export class Creature extends Vore implements Combatant {
     super()
     const containers = this.containers
 
+    this.actions.push(new PassAction())
     Object.entries(this.maxVigors).forEach(([key, val]) => {
       this.vigors[key as Vigor] = val
     })