diff --git a/common/src/comp/buff.rs b/common/src/comp/buff.rs
index c2b9073368..ca1d690002 100644
--- a/common/src/comp/buff.rs
+++ b/common/src/comp/buff.rs
@@ -41,6 +41,7 @@ pub enum BuffCategoryId {
     Divine,
     Debuff,
     Buff,
+    PersistOnDeath,
 }
 
 /// Data indicating and configuring behaviour of a de/buff.
@@ -93,9 +94,12 @@ pub enum BuffChange {
     RemoveByIndex(Vec<usize>, Vec<usize>),
     /// Removes buffs of these categories (first vec is of categories of which
     /// all are required, second vec is of categories of which at least one is
-    /// required) Note that this functionality is currently untested and
-    /// should be tested when doing so is possible
-    RemoveByCategory(Vec<BuffCategoryId>, Vec<BuffCategoryId>),
+    /// required, third vec is of categories that will not be removed)  
+    RemoveByCategory {
+        required: Vec<BuffCategoryId>,
+        optional: Vec<BuffCategoryId>,
+        blacklisted: Vec<BuffCategoryId>,
+    },
 }
 
 /// Source of the de/buff
@@ -173,6 +177,13 @@ impl Buff {
                 duration,
             ),
         };
+        assert_eq!(
+            cat_ids
+                .iter()
+                .any(|cat| *cat == BuffCategoryId::Buff || *cat == BuffCategoryId::Debuff),
+            true,
+            "Buff must have either buff or debuff category."
+        );
         Buff {
             id,
             cat_ids,
diff --git a/common/src/sys/buff.rs b/common/src/sys/buff.rs
index da1b9eee4d..e509d5114b 100644
--- a/common/src/sys/buff.rs
+++ b/common/src/sys/buff.rs
@@ -1,5 +1,8 @@
 use crate::{
-    comp::{BuffChange, BuffEffect, BuffSource, Buffs, HealthChange, HealthSource},
+    comp::{
+        BuffCategoryId, BuffChange, BuffEffect, BuffSource, Buffs, HealthChange, HealthSource,
+        Stats,
+    },
     event::{EventBus, ServerEvent},
     state::DeltaTime,
     sync::Uid,
@@ -14,12 +17,13 @@ impl<'a> System<'a> for Sys {
         Read<'a, DeltaTime>,
         Read<'a, EventBus<ServerEvent>>,
         ReadStorage<'a, Uid>,
+        ReadStorage<'a, Stats>,
         WriteStorage<'a, Buffs>,
     );
 
-    fn run(&mut self, (dt, server_bus, uids, mut buffs): Self::SystemData) {
+    fn run(&mut self, (dt, server_bus, uids, stats, mut buffs): Self::SystemData) {
         let mut server_emitter = server_bus.emitter();
-        for (uid, mut buffs) in (&uids, &mut buffs.restrict_mut()).join() {
+        for (uid, stat, mut buffs) in (&uids, &stats, &mut buffs.restrict_mut()).join() {
             let buff_comp = buffs.get_mut_unchecked();
             let (mut active_buff_indices_for_removal, mut inactive_buff_indices_for_removal) =
                 (Vec::<usize>::new(), Vec::<usize>::new());
@@ -95,6 +99,7 @@ impl<'a> System<'a> for Sys {
                     };
                 }
             }
+
             server_emitter.emit(ServerEvent::Buff {
                 uid: *uid,
                 buff_change: BuffChange::RemoveByIndex(
@@ -102,6 +107,17 @@ impl<'a> System<'a> for Sys {
                     inactive_buff_indices_for_removal,
                 ),
             });
+
+            if stat.is_dead {
+                server_emitter.emit(ServerEvent::Buff {
+                    uid: *uid,
+                    buff_change: BuffChange::RemoveByCategory {
+                        required: vec![],
+                        optional: vec![],
+                        blacklisted: vec![BuffCategoryId::PersistOnDeath],
+                    },
+                });
+            }
         }
     }
 }
diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs
index a0b24b1db7..6e46d94d6d 100644
--- a/common/src/sys/combat.rs
+++ b/common/src/sys/combat.rs
@@ -159,7 +159,7 @@ impl<'a> System<'a> for Sys {
                                     strength: attack.base_damage as f32,
                                     duration: Some(Duration::from_secs(10)),
                                 },
-                                vec![buff::BuffCategoryId::Physical],
+                                vec![buff::BuffCategoryId::Physical, buff::BuffCategoryId::Debuff],
                                 buff::BuffSource::Character { by: *uid },
                             )),
                         });
diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs
index 1e2ed26a2a..d0ba6ee4d6 100644
--- a/server/src/events/entity_manipulation.rs
+++ b/server/src/events/entity_manipulation.rs
@@ -758,7 +758,11 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
                         }
                     }
                 },
-                BuffChange::RemoveByCategory(all_required, any_required) => {
+                BuffChange::RemoveByCategory {
+                    required: all_required,
+                    optional: any_required,
+                    blacklisted: none_required,
+                } => {
                     for (i, buff) in buffs.active_buffs.iter().enumerate() {
                         let mut required_met = true;
                         for required in &all_required {
@@ -774,7 +778,14 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
                                 break;
                             }
                         }
-                        if required_met && any_met {
+                        let mut none_met = true;
+                        for none in &none_required {
+                            if buff.cat_ids.iter().any(|cat| cat == none) {
+                                none_met = false;
+                                break;
+                            }
+                        }
+                        if required_met && any_met && none_met {
                             active_buff_indices_for_removal.push(i);
                         }
                     }
diff --git a/voxygen/src/hud/buffs.rs b/voxygen/src/hud/buffs.rs
index 875c63d779..ad32915443 100644
--- a/voxygen/src/hud/buffs.rs
+++ b/voxygen/src/hud/buffs.rs
@@ -8,7 +8,7 @@ use crate::{
     GlobalState,
 };
 use client::Client;
-use common::comp::Stats;
+use common::comp::{self, Buffs};
 use conrod_core::{
     color,
     widget::{self, Button, Image, Rectangle, Text},
@@ -24,8 +24,15 @@ widget_ids! {
         debuff_test,
     }
 }
+
+pub struct BuffInfo {
+    id: comp::BuffId,
+    is_buff: bool,
+    dur: f32,
+}
+
 #[derive(WidgetCommon)]
-pub struct Buffs<'a> {
+pub struct BuffsBar<'a> {
     client: &'a Client,
     imgs: &'a Imgs,
     fonts: &'a ConrodVoxygenFonts,
@@ -35,10 +42,10 @@ pub struct Buffs<'a> {
     rot_imgs: &'a ImgsRot,
     tooltip_manager: &'a mut TooltipManager,
     localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
-    stats: &'a Stats,
+    buffs: &'a Buffs,
 }
 
-impl<'a> Buffs<'a> {
+impl<'a> BuffsBar<'a> {
     #[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
     pub fn new(
         client: &'a Client,
@@ -48,7 +55,7 @@ impl<'a> Buffs<'a> {
         rot_imgs: &'a ImgsRot,
         tooltip_manager: &'a mut TooltipManager,
         localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
-        stats: &'a Stats,
+        buffs: &'a Buffs,
     ) -> Self {
         Self {
             client,
@@ -59,7 +66,7 @@ impl<'a> Buffs<'a> {
             rot_imgs,
             tooltip_manager,
             localized_strings,
-            stats,
+            buffs,
         }
     }
 }
@@ -68,7 +75,7 @@ pub struct State {
     ids: Ids,
 }
 
-impl<'a> Widget for Buffs<'a> {
+impl<'a> Widget for BuffsBar<'a> {
     type Event = ();
     type State = State;
     type Style = ();
@@ -123,3 +130,14 @@ impl<'a> Widget for Buffs<'a> {
             .set(state.ids.buff_test, ui);
     }
 }
+
+fn get_buff_info(buff: comp::Buff) -> BuffInfo {
+    BuffInfo {
+        id: buff.id,
+        is_buff: buff
+            .cat_ids
+            .iter()
+            .any(|cat| *cat == comp::BuffCategoryId::Buff),
+        dur: buff.time.map(|dur| dur.as_secs_f32()).unwrap_or(100.0),
+    }
+}
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index 5b12014c1e..bd3d0575c4 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -25,7 +25,7 @@ pub use hotbar::{SlotContents as HotbarSlotContents, State as HotbarState};
 pub use settings_window::ScaleChange;
 
 use bag::Bag;
-use buffs::Buffs;
+use buffs::BuffsBar;
 use buttons::Buttons;
 use chat::Chat;
 use chrono::NaiveTime;
@@ -1733,6 +1733,7 @@ impl Hud {
         // Bag button and nearby icons
         let ecs = client.state().ecs();
         let stats = ecs.read_storage::<comp::Stats>();
+        let buffs = ecs.read_storage::<comp::Buffs>();
         if let Some(player_stats) = stats.get(client.entity()) {
             match Buttons::new(
                 client,
@@ -1758,8 +1759,8 @@ impl Hud {
         }
 
         // Buffs and Debuffs
-        if let Some(player_stats) = stats.get(client.entity()) {
-            match Buffs::new(
+        if let Some(player_buffs) = buffs.get(client.entity()) {
+            match BuffsBar::new(
                 client,
                 &self.imgs,
                 &self.fonts,
@@ -1767,7 +1768,7 @@ impl Hud {
                 &self.rot_imgs,
                 tooltip_manager,
                 &self.voxygen_i18n,
-                &player_stats,
+                &player_buffs,
             )
             .set(self.ids.buffs, ui_widgets)
             {