diff --git a/assets/common/items/food/apple_stick.ron b/assets/common/items/food/apple_stick.ron
index 5bf9454978..7d5071e5f7 100644
--- a/assets/common/items/food/apple_stick.ron
+++ b/assets/common/items/food/apple_stick.ron
@@ -1,6 +1,6 @@
 ItemDef(
     name: "Apple Stick",
-    description: "Restores 20 Health",
+    description: "Restores 25 Health",
     kind: Consumable(
         kind: "AppleStick",
         effect: Health((
diff --git a/assets/voxygen/element/animation/buff_frame/1.png b/assets/voxygen/element/animation/buff_frame/1.png
new file mode 100644
index 0000000000..e05166cd46
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/1.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/2.png b/assets/voxygen/element/animation/buff_frame/2.png
new file mode 100644
index 0000000000..54c5183ec1
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/2.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/3.png b/assets/voxygen/element/animation/buff_frame/3.png
new file mode 100644
index 0000000000..b0a196aeac
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/3.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/4.png b/assets/voxygen/element/animation/buff_frame/4.png
new file mode 100644
index 0000000000..beceaf397b
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/4.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/5.png b/assets/voxygen/element/animation/buff_frame/5.png
new file mode 100644
index 0000000000..4cb8dc04c1
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/5.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/6.png b/assets/voxygen/element/animation/buff_frame/6.png
new file mode 100644
index 0000000000..4bc7af2a36
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/6.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/7.png b/assets/voxygen/element/animation/buff_frame/7.png
new file mode 100644
index 0000000000..80dcb85b44
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/7.png differ
diff --git a/assets/voxygen/element/animation/buff_frame/8.png b/assets/voxygen/element/animation/buff_frame/8.png
new file mode 100644
index 0000000000..e158dfbb97
Binary files /dev/null and b/assets/voxygen/element/animation/buff_frame/8.png differ
diff --git a/assets/voxygen/element/de_buffs/buff_plus_0.png b/assets/voxygen/element/icons/de_buffs/buff_plus_0.png
similarity index 100%
rename from assets/voxygen/element/de_buffs/buff_plus_0.png
rename to assets/voxygen/element/icons/de_buffs/buff_plus_0.png
diff --git a/assets/voxygen/element/icons/de_buffs/debuff_bleed_0.png b/assets/voxygen/element/icons/de_buffs/debuff_bleed_0.png
new file mode 100644
index 0000000000..4638eeb618
Binary files /dev/null and b/assets/voxygen/element/icons/de_buffs/debuff_bleed_0.png differ
diff --git a/assets/voxygen/element/de_buffs/debuff_skull_0.png b/assets/voxygen/element/icons/de_buffs/debuff_skull_0.png
similarity index 100%
rename from assets/voxygen/element/de_buffs/debuff_skull_0.png
rename to assets/voxygen/element/icons/de_buffs/debuff_skull_0.png
diff --git a/assets/voxygen/i18n/en.ron b/assets/voxygen/i18n/en.ron
index 55355503b8..c85ffe8d27 100644
--- a/assets/voxygen/i18n/en.ron
+++ b/assets/voxygen/i18n/en.ron
@@ -291,6 +291,8 @@ magically infused items?"#,
         "hud.settings.transparency": "Transparency",
         "hud.settings.hotbar": "Hotbar",
         "hud.settings.toggle_shortcuts": "Toggle Shortcuts",
+        "hud.settings.buffs_skillbar": "Buffs at Skillbar",
+        "hud.settings.buffs_mmap": "Buffs at Minimap",
         "hud.settings.toggle_bar_experience": "Toggle Experience Bar",
         "hud.settings.scrolling_combat_text": "Scrolling Combat Text",
         "hud.settings.single_damage_number": "Single Damage Numbers",
@@ -343,9 +345,9 @@ magically infused items?"#,
         "hud.settings.refresh_rate": "Refresh Rate",
         "hud.settings.save_window_size": "Save window size",
         "hud.settings.lighting_rendering_mode": "Lighting Rendering Mode",
-        "hud.settings.lighting_rendering_mode.ashikhmin": "Type A",
-        "hud.settings.lighting_rendering_mode.blinnphong": "Type B",
-        "hud.settings.lighting_rendering_mode.lambertian": "Type L",
+        "hud.settings.lighting_rendering_mode.ashikhmin": "Type A - High    ",
+        "hud.settings.lighting_rendering_mode.blinnphong": "Type B - Medium",
+        "hud.settings.lighting_rendering_mode.lambertian": "Type L - Cheap",
         "hud.settings.shadow_rendering_mode": "Shadow Rendering Mode",
         "hud.settings.shadow_rendering_mode.none": "None",
         "hud.settings.shadow_rendering_mode.cheap": "Cheap",
@@ -509,6 +511,16 @@ Protection
         "esc_menu.quit_game": "Quit Game",
         /// End Escape Menu Section
 
+        /// Buffs and Debuffs
+        "buff.remove": "Click to remove",
+        "buff.title.missing": "Missing Title", 
+        "buff.desc.missing": "Missing Description", 
+        // Buffs
+        "buff.title.heal_test": "Heal Test", 
+        "buff.desc.heal_test": "This is a test buff to test healing.",   
+        // Debuffs   
+        "debuff.title.bleed_test": "Bleed Test", 
+        "debuff.desc.bleed_test": "This is a test debuff to test bleeding.",
     },
 
 
diff --git a/client/src/lib.rs b/client/src/lib.rs
index ad47263340..9342123523 100644
--- a/client/src/lib.rs
+++ b/client/src/lib.rs
@@ -37,6 +37,7 @@ use common::{
     terrain::{block::Block, neighbors, TerrainChunk, TerrainChunkSize},
     vol::RectVolSize,
 };
+use comp::BuffId;
 use futures_executor::block_on;
 use futures_timer::Delay;
 use futures_util::{select, FutureExt};
@@ -631,6 +632,12 @@ impl Client {
         self.send_msg(ClientGeneral::ControlEvent(ControlEvent::DisableLantern));
     }
 
+    pub fn remove_buff(&mut self, buff_id: BuffId) {
+        self.send_msg(ClientGeneral::ControlEvent(ControlEvent::RemoveBuff(
+            buff_id,
+        )));
+    }
+
     pub fn max_group_size(&self) -> u32 { self.max_group_size }
 
     pub fn group_invite(&self) -> Option<(Uid, std::time::Instant, std::time::Duration)> {
diff --git a/common/src/comp/buff.rs b/common/src/comp/buff.rs
index ca1d690002..828cf39d96 100644
--- a/common/src/comp/buff.rs
+++ b/common/src/comp/buff.rs
@@ -151,16 +151,10 @@ impl Buff {
     pub fn new(id: BuffId, cat_ids: Vec<BuffCategoryId>, source: BuffSource) -> Self {
         let (effects, time) = match id {
             BuffId::Bleeding { strength, duration } => (
-                vec![
-                    BuffEffect::HealthChangeOverTime {
-                        rate: -strength,
-                        accumulated: 0.0,
-                    },
-                    // This effect is for testing purposes
-                    BuffEffect::NameChange {
-                        prefix: String::from("Injured "),
-                    },
-                ],
+                vec![BuffEffect::HealthChangeOverTime {
+                    rate: -strength,
+                    accumulated: 0.0,
+                }],
                 duration,
             ),
             BuffId::Regeneration { strength, duration } => (
diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs
index b9c7e1cb4c..64cdf93505 100644
--- a/common/src/comp/controller.rs
+++ b/common/src/comp/controller.rs
@@ -1,4 +1,8 @@
-use crate::{comp::inventory::slot::Slot, sync::Uid, util::Dir};
+use crate::{
+    comp::{inventory::slot::Slot, BuffId},
+    sync::Uid,
+    util::Dir,
+};
 use serde::{Deserialize, Serialize};
 use specs::{Component, FlaggedStorage};
 use specs_idvs::IdvStorage;
@@ -37,6 +41,7 @@ pub enum ControlEvent {
     Unmount,
     InventoryManip(InventoryManip),
     GroupManip(GroupManip),
+    RemoveBuff(BuffId),
     Respawn,
 }
 
diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs
index 06d39cb1c8..63f263a765 100644
--- a/common/src/sys/agent.rs
+++ b/common/src/sys/agent.rs
@@ -684,7 +684,7 @@ impl<'a> System<'a> for Sys {
         for (_invite, /*alignment,*/ agent, controller) in
             (&invites, /*&alignments,*/ &mut agents, &mut controllers).join()
         {
-            let accept = false; // set back to "matches!(alignment, Alignment::Npc)" when we got better NPC recruitment mechanics
+            let accept = true; // set back to "matches!(alignment, Alignment::Npc)" when we got better NPC recruitment mechanics
             if accept {
                 // Clear agent comp
                 *agent = Agent::default();
diff --git a/common/src/sys/buff.rs b/common/src/sys/buff.rs
index e509d5114b..a959ef3729 100644
--- a/common/src/sys/buff.rs
+++ b/common/src/sys/buff.rs
@@ -62,7 +62,7 @@ impl<'a> System<'a> for Sys {
                         BuffEffect::HealthChangeOverTime { rate, accumulated } => {
                             *accumulated += *rate * buff_delta;
                             // Apply only 0.5 or higher damage
-                            if accumulated.abs() > 5.0 {
+                            if accumulated.abs() > 50.0 {
                                 let cause = if *accumulated > 0.0 {
                                     HealthSource::Healing { by: buff_owner }
                                 } else {
diff --git a/common/src/sys/combat.rs b/common/src/sys/combat.rs
index 6e46d94d6d..7eb6cd53a7 100644
--- a/common/src/sys/combat.rs
+++ b/common/src/sys/combat.rs
@@ -157,12 +157,31 @@ impl<'a> System<'a> for Sys {
                             buff_change: buff::BuffChange::Add(buff::Buff::new(
                                 buff::BuffId::Bleeding {
                                     strength: attack.base_damage as f32,
-                                    duration: Some(Duration::from_secs(10)),
+                                    duration: Some(Duration::from_secs(30)),
                                 },
                                 vec![buff::BuffCategoryId::Physical, buff::BuffCategoryId::Debuff],
                                 buff::BuffSource::Character { by: *uid },
                             )),
                         });
+                        server_emitter.emit(ServerEvent::Buff {
+                            uid: *uid_b,
+                            buff_change: buff::BuffChange::Add(buff::Buff::new(
+                                buff::BuffId::Regeneration {
+                                    strength: 100.0,
+                                    duration: Some(Duration::from_secs(60)),
+                                },
+                                vec![buff::BuffCategoryId::Physical, buff::BuffCategoryId::Buff],
+                                buff::BuffSource::Character { by: *uid },
+                            )),
+                        });
+                        server_emitter.emit(ServerEvent::Buff {
+                            uid: *uid_b,
+                            buff_change: buff::BuffChange::Add(buff::Buff::new(
+                                buff::BuffId::Cursed { duration: None },
+                                vec![buff::BuffCategoryId::Physical, buff::BuffCategoryId::Debuff],
+                                buff::BuffSource::Character { by: *uid },
+                            )),
+                        });
                         attack.hit_count += 1;
                     }
                     if attack.knockback != 0.0 && damage.healthchange != 0.0 {
diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs
index 380b176adf..03fbf46c6e 100644
--- a/common/src/sys/controller.rs
+++ b/common/src/sys/controller.rs
@@ -1,7 +1,7 @@
 use crate::{
     comp::{
         slot::{EquipSlot, Slot},
-        CharacterState, ControlEvent, Controller, InventoryManip,
+        BuffChange, CharacterState, ControlEvent, Controller, InventoryManip,
     },
     event::{EventBus, LocalEvent, ServerEvent},
     metrics::SysMetrics,
@@ -51,7 +51,7 @@ impl<'a> System<'a> for Sys {
         span!(_guard, "run", "controller::Sys::run");
         let mut server_emitter = server_bus.emitter();
 
-        for (entity, _uid, controller, character_state) in
+        for (entity, uid, controller, character_state) in
             (&entities, &uids, &mut controllers, &mut character_states).join()
         {
             let mut inputs = &mut controller.inputs;
@@ -83,6 +83,12 @@ impl<'a> System<'a> for Sys {
                             server_emitter.emit(ServerEvent::Mount(entity, mountee_entity));
                         }
                     },
+                    ControlEvent::RemoveBuff(buff_id) => {
+                        server_emitter.emit(ServerEvent::Buff {
+                            uid: *uid,
+                            buff_change: BuffChange::RemoveById(buff_id),
+                        });
+                    },
                     ControlEvent::Unmount => server_emitter.emit(ServerEvent::Unmount(entity)),
                     ControlEvent::EnableLantern => {
                         server_emitter.emit(ServerEvent::EnableLantern(entity))
diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs
index d0ba6ee4d6..8d7e1b106e 100644
--- a/server/src/events/entity_manipulation.rs
+++ b/server/src/events/entity_manipulation.rs
@@ -715,6 +715,7 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
                         add_buff_effects(new_buff.clone(), stats.get_mut(entity));
                         buffs.active_buffs.push(new_buff);
                     } else {
+                        let mut duplicate_existed = false;
                         for i in 0..buffs.active_buffs.len() {
                             let active_buff = &buffs.active_buffs[i];
                             // Checks if new buff has the same id as an already active buff. If it
@@ -724,6 +725,7 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
                             // inactive buffs and add new buff to active
                             // buffs.
                             if discriminant(&active_buff.id) == discriminant(&new_buff.id) {
+                                duplicate_existed = true;
                                 if determine_replace_active_buff(
                                     active_buff.clone(),
                                     new_buff.clone(),
@@ -731,14 +733,21 @@ pub fn handle_buff(server: &mut Server, uid: Uid, buff_change: buff::BuffChange)
                                     active_buff_indices_for_removal.push(i);
                                     add_buff_effects(new_buff.clone(), stats.get_mut(entity));
                                     buffs.active_buffs.push(new_buff.clone());
-                                } else {
-                                    buffs.inactive_buffs.push(new_buff.clone());
+                                } else if let Some(active_dur) = active_buff.time {
+                                    if let Some(new_dur) = new_buff.time {
+                                        if new_dur > active_dur {
+                                            buffs.inactive_buffs.push(new_buff.clone());
+                                        }
+                                    } else {
+                                        buffs.inactive_buffs.push(new_buff.clone());
+                                    }
                                 }
-                            } else {
-                                add_buff_effects(new_buff.clone(), stats.get_mut(entity));
-                                buffs.active_buffs.push(new_buff.clone());
                             }
                         }
+                        if !duplicate_existed {
+                            add_buff_effects(new_buff.clone(), stats.get_mut(entity));
+                            buffs.active_buffs.push(new_buff.clone());
+                        }
                     }
                 },
                 BuffChange::RemoveByIndex(active_indices, inactive_indices) => {
@@ -871,7 +880,7 @@ fn determine_replace_active_buff(active_buff: buff::Buff, new_buff: buff::Buff)
                 duration: _,
             } = active_buff.id
             {
-                new_strength > active_strength
+                new_strength >= active_strength
             } else {
                 false
             }
@@ -885,7 +894,7 @@ fn determine_replace_active_buff(active_buff: buff::Buff, new_buff: buff::Buff)
                 duration: _,
             } = active_buff.id
             {
-                new_strength > active_strength
+                new_strength >= active_strength
             } else {
                 false
             }
diff --git a/voxygen/src/hud/buffs.rs b/voxygen/src/hud/buffs.rs
index ad32915443..15a6552399 100644
--- a/voxygen/src/hud/buffs.rs
+++ b/voxygen/src/hud/buffs.rs
@@ -1,20 +1,23 @@
 use super::{
     img_ids::{Imgs, ImgsRot},
-    TEXT_COLOR,
+    BUFF_COLOR, DEBUFF_COLOR, TEXT_COLOR,
 };
 use crate::{
+    hud::{get_buff_info, BuffPosition},
     i18n::VoxygenLocalization,
     ui::{fonts::ConrodVoxygenFonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
     GlobalState,
 };
-use client::Client;
-use common::comp::{self, Buffs};
+
+use crate::hud::BuffInfo;
+use common::comp::{BuffId, Buffs};
 use conrod_core::{
     color,
-    widget::{self, Button, Image, Rectangle, Text},
-    widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
+    widget::{self, Button, Image, Rectangle},
+    widget_ids, Color, Positionable, Sizeable, Widget, WidgetCommon,
 };
 use inline_tweak::*;
+use std::time::Duration;
 widget_ids! {
     struct Ids {
         align,
@@ -22,51 +25,49 @@ widget_ids! {
         debuffs_align,
         buff_test,
         debuff_test,
+        buffs[],
+        buff_timers[],
+        debuffs[],
+        debuff_timers[],
     }
 }
 
-pub struct BuffInfo {
-    id: comp::BuffId,
-    is_buff: bool,
-    dur: f32,
-}
-
 #[derive(WidgetCommon)]
 pub struct BuffsBar<'a> {
-    client: &'a Client,
     imgs: &'a Imgs,
     fonts: &'a ConrodVoxygenFonts,
     #[conrod(common_builder)]
     common: widget::CommonBuilder,
-    global_state: &'a GlobalState,
     rot_imgs: &'a ImgsRot,
     tooltip_manager: &'a mut TooltipManager,
     localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
     buffs: &'a Buffs,
+    pulse: f32,
+    global_state: &'a GlobalState,
 }
 
 impl<'a> BuffsBar<'a> {
     #[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
     pub fn new(
-        client: &'a Client,
         imgs: &'a Imgs,
         fonts: &'a ConrodVoxygenFonts,
-        global_state: &'a GlobalState,
         rot_imgs: &'a ImgsRot,
         tooltip_manager: &'a mut TooltipManager,
         localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
         buffs: &'a Buffs,
+        pulse: f32,
+        global_state: &'a GlobalState,
     ) -> Self {
         Self {
-            client,
             imgs,
             fonts,
             common: widget::CommonBuilder::default(),
-            global_state,
             rot_imgs,
             tooltip_manager,
             localized_strings,
             buffs,
+            pulse,
+            global_state,
         }
     }
 }
@@ -75,8 +76,12 @@ pub struct State {
     ids: Ids,
 }
 
+pub enum Event {
+    RemoveBuff(BuffId),
+}
+
 impl<'a> Widget for BuffsBar<'a> {
-    type Event = ();
+    type Event = Vec<Event>;
     type State = State;
     type Style = ();
 
@@ -91,7 +96,11 @@ impl<'a> Widget for BuffsBar<'a> {
 
     fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
         let widget::UpdateArgs { state, ui, .. } = args;
+        let mut event = Vec::new();
         let localized_strings = self.localized_strings;
+        let buffs = self.buffs;
+        let buff_ani = ((self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8) + 0.5; //Animation timer
+        let buff_position = self.global_state.settings.gameplay.buff_position;
         let buffs_tooltip = Tooltip::new({
             // Edge images [t, b, r, l]
             // Corner images [tr, tl, br, bl]
@@ -109,35 +118,230 @@ impl<'a> Widget for BuffsBar<'a> {
         .desc_font_size(self.fonts.cyri.scale(12))
         .font_id(self.fonts.cyri.conrod_id)
         .desc_text_color(TEXT_COLOR);
-        // Alignment
-        Rectangle::fill_with([484.0, 100.0], color::TRANSPARENT)
-            .mid_bottom_with_margin_on(ui.window, tweak!(92.0))
-            .set(state.ids.align, ui);
-        Rectangle::fill_with([484.0 / 2.0, 90.0], color::TRANSPARENT)
-            .bottom_left_with_margins_on(state.ids.align, 0.0, 0.0)
-            .set(state.ids.debuffs_align, ui);
-        Rectangle::fill_with([484.0 / 2.0, 90.0], color::TRANSPARENT)
-            .bottom_right_with_margins_on(state.ids.align, 0.0, 0.0)
-            .set(state.ids.buffs_align, ui);
-        // Test Widgets
-        Image::new(self.imgs.debuff_skull_0)
-            .w_h(20.0, 20.0)
-            .bottom_right_with_margins_on(state.ids.debuffs_align, 0.0, 1.0)
-            .set(state.ids.debuff_test, ui);
-        Image::new(self.imgs.buff_plus_0)
-            .w_h(20.0, 20.0)
-            .bottom_left_with_margins_on(state.ids.buffs_align, 0.0, 1.0)
-            .set(state.ids.buff_test, ui);
-    }
-}
+        if let BuffPosition::Bar = buff_position {
+            // Alignment
+            Rectangle::fill_with([484.0, 100.0], color::TRANSPARENT)
+                .mid_bottom_with_margin_on(ui.window, tweak!(92.0))
+                .set(state.ids.align, ui);
+            Rectangle::fill_with([484.0 / 2.0, 90.0], color::TRANSPARENT)
+                .bottom_left_with_margins_on(state.ids.align, 0.0, 0.0)
+                .set(state.ids.debuffs_align, ui);
+            Rectangle::fill_with([484.0 / 2.0, 90.0], color::TRANSPARENT)
+                .bottom_right_with_margins_on(state.ids.align, 0.0, 0.0)
+                .set(state.ids.buffs_align, 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),
+            // Buffs and Debuffs
+            // Create two vecs to display buffs and debuffs separately
+            let mut buffs_vec = Vec::<BuffInfo>::new();
+            let mut debuffs_vec = Vec::<BuffInfo>::new();
+            for buff in buffs.active_buffs.clone() {
+                let info = get_buff_info(buff);
+                if info.is_buff {
+                    buffs_vec.push(info);
+                } else {
+                    debuffs_vec.push(info);
+                }
+            }
+            if state.ids.buffs.len() < buffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .buffs
+                        .resize(buffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            if state.ids.debuffs.len() < debuffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .debuffs
+                        .resize(debuffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            if state.ids.buff_timers.len() < buffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .buff_timers
+                        .resize(buffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            if state.ids.debuff_timers.len() < debuffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .debuff_timers
+                        .resize(debuffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
+            let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
+            // Create Buff Widgets
+            for (i, buff) in buffs_vec.iter().enumerate() {
+                if i < 22 {
+                    // Limit displayed buffs
+                    let max_duration = match buff.id {
+                        BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
+                        _ => 10.0,
+                    };
+                    let current_duration = buff.dur;
+                    let duration_percentage = (current_duration / max_duration * 1000.0) as u32; // Percentage to determine which frame of the timer overlay is displayed
+                    let buff_img = match buff.id {
+                        BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
+                        _ => self.imgs.missing_icon,
+                    };
+                    let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
+                    // Sort buffs into rows of 11 slots
+                    let x = i % 11;
+                    let y = i / 11;
+                    let buff_widget = buff_widget.bottom_left_with_margins_on(
+                        state.ids.buffs_align,
+                        0.0 + y as f64 * (21.0),
+                        0.0 + x as f64 * (21.0),
+                    );
+                    buff_widget
+                        .color(if current_duration < 10.0 {
+                            Some(pulsating_col)
+                        } else {
+                            Some(norm_col)
+                        })
+                        .set(state.ids.buffs[i], ui);
+                    // Create Buff tooltip
+                    let title = match buff.id {
+                        BuffId::Regeneration { .. } => {
+                            *&localized_strings.get("buff.title.heal_test")
+                        },
+                        _ => *&localized_strings.get("buff.title.missing"),
+                    };
+                    let remaining_time = if current_duration == 10e6 as f32 {
+                        "Permanent".to_string()
+                    } else {
+                        format!("Remaining: {:.0}s", current_duration)
+                    };
+                    let click_to_remove = format!("<{}>", &localized_strings.get("buff.remove"));
+                    let desc_txt = match buff.id {
+                        BuffId::Regeneration { .. } => {
+                            *&localized_strings.get("buff.desc.heal_test")
+                        },
+                        _ => *&localized_strings.get("buff.desc.missing"),
+                    };
+                    let desc = format!("{}\n\n{}\n\n{}", desc_txt, remaining_time, click_to_remove);
+                    // Timer overlay
+                    if Button::image(match duration_percentage as u64 {
+                        875..=1000 => self.imgs.nothing, // 8/8
+                        750..=874 => self.imgs.buff_0,   // 7/8
+                        625..=749 => self.imgs.buff_1,   // 6/8
+                        500..=624 => self.imgs.buff_2,   // 5/8
+                        375..=499 => self.imgs.buff_3,   // 4/8
+                        250..=374 => self.imgs.buff_4,   //3/8
+                        125..=249 => self.imgs.buff_5,   // 2/8
+                        0..=124 => self.imgs.buff_6,     // 1/8
+                        _ => self.imgs.nothing,
+                    })
+                    .w_h(20.0, 20.0)
+                    .middle_of(state.ids.buffs[i])
+                    .with_tooltip(
+                        self.tooltip_manager,
+                        title,
+                        &desc,
+                        &buffs_tooltip,
+                        BUFF_COLOR,
+                    )
+                    .set(state.ids.buff_timers[i], ui)
+                    .was_clicked()
+                    {
+                        event.push(Event::RemoveBuff(buff.id));
+                    };
+                };
+            }
+            // Create Debuff Widgets
+            for (i, debuff) in debuffs_vec.iter().enumerate() {
+                if i < 22 {
+                    // Limit displayed buffs
+
+                    let max_duration = match debuff.id {
+                        BuffId::Bleeding { duration, .. } => {
+                            duration.unwrap_or(Duration::from_secs(60)).as_secs_f32()
+                        },
+                        BuffId::Cursed { duration, .. } => {
+                            duration.unwrap_or(Duration::from_secs(60)).as_secs_f32()
+                        },
+
+                        _ => 10.0,
+                    };
+                    let current_duration = debuff.dur;
+                    let duration_percentage = current_duration / max_duration * 1000.0; // Percentage to determine which frame of the timer overlay is displayed           
+                    let debuff_img = match debuff.id {
+                        BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
+                        BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
+                        _ => self.imgs.missing_icon,
+                    };
+                    let debuff_widget = Image::new(debuff_img).w_h(20.0, 20.0);
+                    // Sort buffs into rows of 11 slots
+                    let x = i % 11;
+                    let y = i / 11;
+                    let debuff_widget = debuff_widget.bottom_right_with_margins_on(
+                        state.ids.debuffs_align,
+                        0.0 + y as f64 * (21.0),
+                        0.0 + x as f64 * (21.0),
+                    );
+
+                    debuff_widget
+                        .color(if current_duration < 10.0 {
+                            Some(pulsating_col)
+                        } else {
+                            Some(norm_col)
+                        })
+                        .set(state.ids.debuffs[i], ui);
+                    // Create Debuff tooltip
+                    let title = match debuff.id {
+                        BuffId::Bleeding { .. } => {
+                            *&localized_strings.get("debuff.title.bleed_test")
+                        },
+                        _ => *&localized_strings.get("buff.title.missing"),
+                    };
+                    let remaining_time = if current_duration == 10e6 as f32 {
+                        "Permanent".to_string()
+                    } else {
+                        format!("Remaining: {:.0}s", current_duration)
+                    };
+                    let desc_txt = match debuff.id {
+                        BuffId::Bleeding { .. } => {
+                            *&localized_strings.get("debuff.desc.bleed_test")
+                        },
+                        _ => *&localized_strings.get("debuff.desc.missing"),
+                    };
+                    let desc = format!("{}\n\n{}", desc_txt, remaining_time);
+                    Image::new(match duration_percentage as u64 {
+                        875..=1000 => self.imgs.nothing, // 8/8
+                        750..=874 => self.imgs.buff_0,   // 7/8
+                        625..=749 => self.imgs.buff_1,   // 6/8
+                        500..=624 => self.imgs.buff_2,   // 5/8
+                        375..=499 => self.imgs.buff_3,   // 4/8
+                        250..=374 => self.imgs.buff_4,   //3/8
+                        125..=249 => self.imgs.buff_5,   // 2/8
+                        0..=124 => self.imgs.buff_6,     // 1/8
+                        _ => self.imgs.nothing,
+                    })
+                    .w_h(20.0, 20.0)
+                    .middle_of(state.ids.debuffs[i])
+                    .with_tooltip(
+                        self.tooltip_manager,
+                        title,
+                        &desc,
+                        &buffs_tooltip,
+                        DEBUFF_COLOR,
+                    )
+                    .set(state.ids.debuff_timers[i], ui);
+                };
+            }
+        }
+        if let BuffPosition::Map = buff_position {
+            // Alignment
+            Rectangle::fill_with([tweak!(300.0), tweak!(280.0)], color::RED)
+                .top_right_with_margins_on(ui.window, tweak!(5.0), tweak!(270.0))
+                .set(state.ids.align, ui);
+        }
+        event
     }
 }
diff --git a/voxygen/src/hud/group.rs b/voxygen/src/hud/group.rs
index 26b853cd08..06503bc9d8 100644
--- a/voxygen/src/hud/group.rs
+++ b/voxygen/src/hud/group.rs
@@ -1,15 +1,20 @@
 use super::{
-    img_ids::Imgs, Show, BLACK, ERROR_COLOR, GROUP_COLOR, HP_COLOR, KILL_COLOR, LOW_HP_COLOR,
-    STAMINA_COLOR, TEXT_COLOR, TEXT_COLOR_GREY, UI_HIGHLIGHT_0, UI_MAIN,
+    img_ids::{Imgs, ImgsRot},
+    Show, BLACK, BUFF_COLOR, DEBUFF_COLOR, ERROR_COLOR, GROUP_COLOR, HP_COLOR, KILL_COLOR,
+    LOW_HP_COLOR, STAMINA_COLOR, TEXT_COLOR, TEXT_COLOR_GREY, UI_HIGHLIGHT_0, UI_MAIN,
 };
 
 use crate::{
-    i18n::VoxygenLocalization, settings::Settings, ui::fonts::ConrodVoxygenFonts,
-    window::GameInput, GlobalState,
+    hud::{get_buff_info, BuffInfo},
+    i18n::VoxygenLocalization,
+    settings::Settings,
+    ui::{fonts::ConrodVoxygenFonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
+    window::GameInput,
+    GlobalState,
 };
 use client::{self, Client};
 use common::{
-    comp::{group::Role, Stats},
+    comp::{group::Role, BuffId, Buffs, Stats},
     sync::{Uid, WorldSyncExt},
 };
 use conrod_core::{
@@ -18,8 +23,8 @@ use conrod_core::{
     widget::{self, Button, Image, Rectangle, Scrollbar, Text},
     widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
 };
+use inline_tweak::*;
 use specs::{saveload::MarkerAllocator, WorldExt};
-
 widget_ids! {
     pub struct Ids {
         group_button,
@@ -44,6 +49,8 @@ widget_ids! {
         member_panels_txt[],
         member_health[],
         member_stam[],
+        buffs[],
+        buff_timers[],
         dead_txt[],
         health_txt[],
         timeout_bg,
@@ -63,10 +70,13 @@ pub struct Group<'a> {
     client: &'a Client,
     settings: &'a Settings,
     imgs: &'a Imgs,
+    rot_imgs: &'a ImgsRot,
     fonts: &'a ConrodVoxygenFonts,
     localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
     pulse: f32,
     global_state: &'a GlobalState,
+    buffs: &'a Buffs,
+    tooltip_manager: &'a mut TooltipManager,
 
     #[conrod(common_builder)]
     common: widget::CommonBuilder,
@@ -79,20 +89,26 @@ impl<'a> Group<'a> {
         client: &'a Client,
         settings: &'a Settings,
         imgs: &'a Imgs,
+        rot_imgs: &'a ImgsRot,
         fonts: &'a ConrodVoxygenFonts,
         localized_strings: &'a std::sync::Arc<VoxygenLocalization>,
         pulse: f32,
         global_state: &'a GlobalState,
+        buffs: &'a Buffs,
+        tooltip_manager: &'a mut TooltipManager,
     ) -> Self {
         Self {
             show,
             client,
             settings,
             imgs,
+            rot_imgs,
             fonts,
             localized_strings,
             pulse,
             global_state,
+            buffs,
+            tooltip_manager,
             common: widget::CommonBuilder::default(),
         }
     }
@@ -127,8 +143,27 @@ impl<'a> Widget for Group<'a> {
     #[allow(clippy::blocks_in_if_conditions)] // TODO: Pending review in #587
     fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
         let widget::UpdateArgs { state, ui, .. } = args;
-
         let mut events = Vec::new();
+        let localized_strings = self.localized_strings;
+        //let buffs = self.buffs;
+        let buff_ani = ((self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8) + 0.5; //Animation timer
+        let buffs_tooltip = Tooltip::new({
+            // Edge images [t, b, r, l]
+            // Corner images [tr, tl, br, bl]
+            let edge = &self.rot_imgs.tt_side;
+            let corner = &self.rot_imgs.tt_corner;
+            ImageFrame::new(
+                [edge.cw180, edge.none, edge.cw270, edge.cw90],
+                [corner.none, corner.cw270, corner.cw90, corner.cw180],
+                Color::Rgba(0.08, 0.07, 0.04, 1.0),
+                5.0,
+            )
+        })
+        .title_font_size(self.fonts.cyri.scale(15))
+        .parent(ui.window)
+        .desc_font_size(self.fonts.cyri.scale(12))
+        .font_id(self.fonts.cyri.conrod_id)
+        .desc_text_color(TEXT_COLOR);
 
         // Don't show pets
         let group_members = self
@@ -293,6 +328,7 @@ impl<'a> Widget for Group<'a> {
             let client_state = self.client.state();
             let stats = client_state.ecs().read_storage::<common::comp::Stats>();
             let energy = client_state.ecs().read_storage::<common::comp::Energy>();
+            let buffs = client_state.ecs().read_storage::<common::comp::Buffs>();
             let uid_allocator = client_state
                 .ecs()
                 .read_resource::<common::sync::UidAllocator>();
@@ -302,6 +338,8 @@ impl<'a> Widget for Group<'a> {
                 let entity = uid_allocator.retrieve_entity_internal(uid.into());
                 let stats = entity.and_then(|entity| stats.get(entity));
                 let energy = entity.and_then(|entity| energy.get(entity));
+                let buffs = entity.and_then(|entity| buffs.get(entity));
+
                 if let Some(stats) = stats {
                     let char_name = stats.name.to_string();
                     let health_perc = stats.health.current() as f64 / stats.health.maximum() as f64;
@@ -317,7 +355,7 @@ impl<'a> Widget for Group<'a> {
                             .top_left_with_margins_on(ui.window, offset, 20.0)
                     } else {
                         Image::new(self.imgs.member_bg)
-                            .down_from(state.ids.member_panels_bg[i - 1], 40.0)
+                            .down_from(state.ids.member_panels_bg[i - 1], 45.0)
                     };
                     let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8; //Animation timer
                     let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
@@ -386,19 +424,19 @@ impl<'a> Widget for Group<'a> {
                         .set(state.ids.member_panels_frame[i], ui);
                     // Panel Text
                     Text::new(&char_name)
-                        .top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 0.0)
-                        .font_size(20)
-                        .font_id(self.fonts.cyri.conrod_id)
-                        .color(BLACK)
-                        .w(300.0) // limit name length display
-                        .set(state.ids.member_panels_txt_bg[i], ui);
+                            .top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 0.0)
+                            .font_size(20)
+                            .font_id(self.fonts.cyri.conrod_id)
+                            .color(BLACK)
+                            .w(300.0) // limit name length display
+                            .set(state.ids.member_panels_txt_bg[i], ui);
                     Text::new(&char_name)
-                        .bottom_left_with_margins_on(state.ids.member_panels_txt_bg[i], 2.0, 2.0)
-                        .font_size(20)
-                        .font_id(self.fonts.cyri.conrod_id)
-                        .color(if is_leader { ERROR_COLOR } else { GROUP_COLOR })
-                        .w(300.0) // limit name length display
-                        .set(state.ids.member_panels_txt[i], ui);
+                            .bottom_left_with_margins_on(state.ids.member_panels_txt_bg[i], 2.0, 2.0)
+                            .font_size(20)
+                            .font_id(self.fonts.cyri.conrod_id)
+                            .color(if is_leader { ERROR_COLOR } else { GROUP_COLOR })
+                            .w(300.0) // limit name length display
+                            .set(state.ids.member_panels_txt[i], ui);
                     if let Some(energy) = energy {
                         let stam_perc = energy.current() as f64 / energy.maximum() as f64;
                         // Stamina
@@ -408,44 +446,146 @@ impl<'a> Widget for Group<'a> {
                             .top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0)
                             .set(state.ids.member_stam[i], ui);
                     }
-                } else {
-                    // Values N.A.
-                    if let Some(stats) = stats {
+                    if let Some(buffs) = buffs {
+                        let mut buffs_vec = Vec::<BuffInfo>::new();
+                        for buff in buffs.active_buffs.clone() {
+                            let info = get_buff_info(buff);
+                            buffs_vec.push(info);
+                        }
+                        state.update(|state| {
+                            state.ids.buffs.resize(
+                                state.ids.buffs.len() + buffs_vec.len(),
+                                &mut ui.widget_id_generator(),
+                            )
+                        });
+                        state.update(|state| {
+                            state.ids.buff_timers.resize(
+                                state.ids.buff_timers.len() + buffs_vec.len(),
+                                &mut ui.widget_id_generator(),
+                            )
+                        });
+                        // Create Buff Widgets
+                        for (x, buff) in buffs_vec.iter().enumerate() {
+                            if x < 11 {
+                                // Limit displayed buffs
+                                let max_duration = match buff.id {
+                                    BuffId::Regeneration { duration, .. } => {
+                                        duration.unwrap().as_secs_f32()
+                                    },
+                                    _ => 10.0,
+                                };
+                                let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
+                                let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
+                                let current_duration = buff.dur;
+                                let duration_percentage =
+                                    (current_duration / max_duration * 1000.0) as u32; // Percentage to determine which frame of the timer overlay is displayed
+                                let buff_img = match buff.id {
+                                    BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
+                                    BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
+                                    BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
+                                };
+                                let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
+                                let buff_widget = if x == 0 {
+                                    buff_widget.bottom_left_with_margins_on(
+                                        state.ids.member_panels_frame[i],
+                                        -21.0,
+                                        1.0,
+                                    )
+                                } else {
+                                    buff_widget.right_from(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x - 1/*x - 1*/], 1.0)
+                                };
+                                buff_widget
+                                    .color(if current_duration < 10.0 {
+                                        Some(pulsating_col)
+                                    } else {
+                                        Some(norm_col)
+                                    })
+                                    .set(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x/*x*/], ui);
+                                // Create Buff tooltip
+                                let title = match buff.id {
+                                    BuffId::Regeneration { .. } => {
+                                        *&localized_strings.get("buff.title.heal_test")
+                                    },
+                                    BuffId::Bleeding { .. } => {
+                                        *&localized_strings.get("debuff.title.bleed_test")
+                                    },
+                                    _ => *&localized_strings.get("buff.title.missing"),
+                                };
+                                let remaining_time = if current_duration == 10e6 as f32 {
+                                    "Permanent".to_string()
+                                } else {
+                                    format!("Remaining: {:.0}s", current_duration)
+                                };
+                                let desc_txt = match buff.id {
+                                    BuffId::Regeneration { .. } => {
+                                        *&localized_strings.get("buff.desc.heal_test")
+                                    },
+                                    BuffId::Bleeding { .. } => {
+                                        *&localized_strings.get("debuff.desc.bleed_test")
+                                    },
+                                    _ => *&localized_strings.get("buff.desc.missing"),
+                                };
+                                let desc = format!("{}\n\n{}", desc_txt, remaining_time);
+                                Image::new(match duration_percentage as u64 {
+                                    875..=1000 => self.imgs.nothing, // 8/8
+                                    750..=874 => self.imgs.buff_0,   // 7/8
+                                    625..=749 => self.imgs.buff_1,   // 6/8
+                                    500..=624 => self.imgs.buff_2,   // 5/8
+                                    375..=499 => self.imgs.buff_3,   // 4/8
+                                    250..=374 => self.imgs.buff_4,   // 3/8
+                                    125..=249 => self.imgs.buff_5,   // 2/8
+                                    0..=124 => self.imgs.buff_6,     // 1/8
+                                    _ => self.imgs.nothing,
+                                })
+                                .w_h(20.0, 20.0)
+                                .middle_of(state.ids.buffs[state.ids.buffs.len() - buffs_vec.len() + x/*x*/])
+                                .with_tooltip(
+                                    self.tooltip_manager,
+                                    title,
+                                    &desc,
+                                    &buffs_tooltip,
+                                    if buff.is_buff {BUFF_COLOR} else {DEBUFF_COLOR},
+                                )
+                                .set(state.ids.buff_timers[state.ids.buffs.len() - buffs_vec.len() + x/*x*/], ui);
+                            };
+                        }
+                    } else {
+                        // Values N.A.
                         Text::new(&stats.name.to_string())
                             .top_left_with_margins_on(state.ids.member_panels_frame[i], -22.0, 0.0)
                             .font_size(20)
                             .font_id(self.fonts.cyri.conrod_id)
                             .color(GROUP_COLOR)
                             .set(state.ids.member_panels_txt[i], ui);
-                    };
-                    let offset = if self.global_state.settings.gameplay.toggle_debug {
-                        210.0
-                    } else {
-                        110.0
-                    };
-                    let back = if i == 0 {
-                        Image::new(self.imgs.member_bg)
-                            .top_left_with_margins_on(ui.window, offset, 20.0)
-                    } else {
-                        Image::new(self.imgs.member_bg)
-                            .down_from(state.ids.member_panels_bg[i - 1], 40.0)
-                    };
-                    back.w_h(152.0, 36.0)
-                        .color(Some(TEXT_COLOR))
-                        .set(state.ids.member_panels_bg[i], ui);
-                    // Panel Frame
-                    Image::new(self.imgs.member_frame)
-                        .w_h(152.0, 36.0)
-                        .middle_of(state.ids.member_panels_bg[i])
-                        .color(Some(UI_HIGHLIGHT_0))
-                        .set(state.ids.member_panels_frame[i], ui);
-                    // Panel Text
-                    Text::new(&self.localized_strings.get("hud.group.out_of_range"))
-                        .mid_top_with_margin_on(state.ids.member_panels_bg[i], 3.0)
-                        .font_size(16)
-                        .font_id(self.fonts.cyri.conrod_id)
-                        .color(TEXT_COLOR)
-                        .set(state.ids.dead_txt[i], ui);
+                        let offset = if self.global_state.settings.gameplay.toggle_debug {
+                            210.0
+                        } else {
+                            110.0
+                        };
+                        let back = if i == 0 {
+                            Image::new(self.imgs.member_bg)
+                                .top_left_with_margins_on(ui.window, offset, 20.0)
+                        } else {
+                            Image::new(self.imgs.member_bg)
+                                .down_from(state.ids.member_panels_bg[i - 1], 40.0)
+                        };
+                        back.w_h(152.0, 36.0)
+                            .color(Some(TEXT_COLOR))
+                            .set(state.ids.member_panels_bg[i], ui);
+                        // Panel Frame
+                        Image::new(self.imgs.member_frame)
+                            .w_h(152.0, 36.0)
+                            .middle_of(state.ids.member_panels_bg[i])
+                            .color(Some(UI_HIGHLIGHT_0))
+                            .set(state.ids.member_panels_frame[i], ui);
+                        // Panel Text
+                        Text::new(&self.localized_strings.get("hud.group.out_of_range"))
+                            .mid_top_with_margin_on(state.ids.member_panels_bg[i], 3.0)
+                            .font_size(16)
+                            .font_id(self.fonts.cyri.conrod_id)
+                            .color(TEXT_COLOR)
+                            .set(state.ids.dead_txt[i], ui);
+                    }
                 }
             }
 
diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs
index 3aced27a57..fbb48033c0 100644
--- a/voxygen/src/hud/img_ids.rs
+++ b/voxygen/src/hud/img_ids.rs
@@ -272,6 +272,7 @@ image_ids! {
         hammerleap: "voxygen.element.icons.skill_hammerleap",
         skill_axe_leap_slash: "voxygen.element.icons.skill_axe_leap_slash",
         skill_bow_jump_burst: "voxygen.element.icons.skill_bow_jump_burst",
+        missing_icon: "voxygen.element.icons.missing_icon_grey",
 
         // Buttons
         button: "voxygen.element.buttons.button",
@@ -350,10 +351,22 @@ image_ids! {
         chat_world: "voxygen.element.icons.chat.world",
 
         // Buffs
-        buff_plus_0: "voxygen.element.de_buffs.buff_plus_0",
+        buff_plus_0: "voxygen.element.icons.de_buffs.buff_plus_0",
 
         // Debuffs
-        debuff_skull_0: "voxygen.element.de_buffs.debuff_skull_0",
+        debuff_skull_0: "voxygen.element.icons.de_buffs.debuff_skull_0",
+        debuff_bleed_0: "voxygen.element.icons.de_buffs.debuff_bleed_0",
+
+        // Animation Frames
+        // Buff Frame
+        buff_0: "voxygen.element.animation.buff_frame.1",
+        buff_1: "voxygen.element.animation.buff_frame.2",
+        buff_2: "voxygen.element.animation.buff_frame.3",
+        buff_3: "voxygen.element.animation.buff_frame.4",
+        buff_4: "voxygen.element.animation.buff_frame.5",
+        buff_5: "voxygen.element.animation.buff_frame.6",
+        buff_6: "voxygen.element.animation.buff_frame.7",
+        buff_7: "voxygen.element.animation.buff_frame.8",
 
         <BlankGraphic>
         nothing: (),
diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs
index 1bdeef1395..ca993285cb 100644
--- a/voxygen/src/hud/minimap.rs
+++ b/voxygen/src/hud/minimap.rs
@@ -105,7 +105,7 @@ impl<'a> Widget for MiniMap<'a> {
     fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
         let widget::UpdateArgs { state, ui, .. } = args;
         let zoom = state.zoom;
-        const SCALE: f64 = 1.5;
+        const SCALE: f64 = 1.5; // TODO Make this a setting
         if self.show.mini_map {
             Image::new(self.imgs.mmap_frame)
                 .w_h(174.0 * SCALE, 190.0 * SCALE)
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index bd3d0575c4..1576fb3ff1 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -60,7 +60,10 @@ use client::Client;
 use common::{
     assets::Asset,
     comp,
-    comp::item::{ItemDesc, Quality},
+    comp::{
+        item::{ItemDesc, Quality},
+        BuffId,
+    },
     span,
     sync::Uid,
     terrain::TerrainChunk,
@@ -97,6 +100,8 @@ const STAMINA_COLOR: Color = Color::Rgba(0.29, 0.62, 0.75, 0.9);
 //const TRANSPARENT: Color = Color::Rgba(0.0, 0.0, 0.0, 0.0);
 //const FOCUS_COLOR: Color = Color::Rgba(1.0, 0.56, 0.04, 1.0);
 //const RAGE_COLOR: Color = Color::Rgba(0.5, 0.04, 0.13, 1.0);
+const BUFF_COLOR: Color = Color::Rgba(0.06, 0.69, 0.12, 1.0);
+const DEBUFF_COLOR: Color = Color::Rgba(0.79, 0.19, 0.17, 1.0);
 
 // Item Quality Colors
 const QUALITY_LOW: Color = Color::Rgba(0.41, 0.41, 0.41, 1.0); // Grey - Trash, can be sold to vendors
@@ -267,6 +272,13 @@ widget_ids! {
     }
 }
 
+#[derive(Clone, Copy)]
+pub struct BuffInfo {
+    id: comp::BuffId,
+    is_buff: bool,
+    dur: f32,
+}
+
 pub struct DebugInfo {
     pub tps: f64,
     pub frame_time: Duration,
@@ -318,6 +330,7 @@ pub enum Event {
     ChatTransp(f32),
     ChatCharName(bool),
     CrosshairType(CrosshairType),
+    BuffPosition(BuffPosition),
     ToggleXpBar(XpBar),
     Intro(Intro),
     ToggleBarNumbers(BarNumbers),
@@ -351,6 +364,7 @@ pub enum Event {
     KickMember(common::sync::Uid),
     LeaveGroup,
     AssignLeader(common::sync::Uid),
+    RemoveBuff(BuffId),
 }
 
 // TODO: Are these the possible layouts we want?
@@ -391,6 +405,13 @@ pub enum ShortcutNumbers {
     On,
     Off,
 }
+
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub enum BuffPosition {
+    Bar,
+    Map,
+}
+
 #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
 pub enum PressBehavior {
     Toggle = 0,
@@ -725,6 +746,7 @@ impl Hud {
             let ecs = client.state().ecs();
             let pos = ecs.read_storage::<comp::Pos>();
             let stats = ecs.read_storage::<comp::Stats>();
+            let buffs = ecs.read_storage::<comp::Buffs>();
             let energy = ecs.read_storage::<comp::Energy>();
             let hp_floater_lists = ecs.read_storage::<vcomp::HpFloaterList>();
             let uids = ecs.read_storage::<common::sync::Uid>();
@@ -1123,11 +1145,12 @@ impl Hud {
             let speech_bubbles = &self.speech_bubbles;
 
             // Render overhead name tags and health bars
-            for (pos, info, bubble, stats, height_offset, hpfl, in_group) in (
+            for (pos, info, bubble, stats, buffs, height_offset, hpfl, in_group) in (
                 &entities,
                 &pos,
                 interpolated.maybe(),
                 &stats,
+                &buffs,
                 energy.maybe(),
                 scales.maybe(),
                 &bodies,
@@ -1141,7 +1164,7 @@ impl Hud {
                     entity != me && !stats.is_dead
                 })
                 .filter_map(
-                    |(entity, pos, interpolated, stats, energy, scale, body, hpfl, uid)| {
+                    |(entity, pos, interpolated, stats, buffs, energy, scale, body, hpfl, uid)| {
                         // Use interpolated position if available
                         let pos = interpolated.map_or(pos.0, |i| i.pos);
                         let in_group = client.group_members().contains_key(uid);
@@ -1171,6 +1194,7 @@ impl Hud {
                         let info = display_overhead_info.then(|| overhead::Info {
                             name: &stats.name,
                             stats,
+                            buffs,
                             energy,
                         });
                         let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
@@ -1185,6 +1209,7 @@ impl Hud {
                                 info,
                                 bubble,
                                 stats,
+                                buffs,
                                 body.height() * scale.map_or(1.0, |s| s.0) + 0.5,
                                 hpfl,
                                 in_group,
@@ -1760,22 +1785,48 @@ impl Hud {
 
         // Buffs and Debuffs
         if let Some(player_buffs) = buffs.get(client.entity()) {
-            match BuffsBar::new(
-                client,
+            for event in BuffsBar::new(
                 &self.imgs,
                 &self.fonts,
-                global_state,
                 &self.rot_imgs,
                 tooltip_manager,
                 &self.voxygen_i18n,
                 &player_buffs,
+                self.pulse,
+                &global_state,
             )
             .set(self.ids.buffs, ui_widgets)
             {
-                _ => {},
+                match event {
+                    buffs::Event::RemoveBuff(buff_id) => events.push(Event::RemoveBuff(buff_id)),
+                }
+            }
+        }
+        // Group Window
+        let buffs = buffs.get(client.entity()).unwrap();
+        for event in Group::new(
+            &mut self.show,
+            client,
+            &global_state.settings,
+            &self.imgs,
+            &self.rot_imgs,
+            &self.fonts,
+            &self.voxygen_i18n,
+            self.pulse,
+            &global_state,
+            &buffs,
+            tooltip_manager,
+        )
+        .set(self.ids.group_window, ui_widgets)
+        {
+            match event {
+                group::Event::Accept => events.push(Event::AcceptInvite),
+                group::Event::Decline => events.push(Event::DeclineInvite),
+                group::Event::Kick(uid) => events.push(Event::KickMember(uid)),
+                group::Event::LeaveGroup => events.push(Event::LeaveGroup),
+                group::Event::AssignLeader(uid) => events.push(Event::AssignLeader(uid)),
             }
         }
-
         // Popup (waypoint saved and similar notifications)
         Popup::new(
             &self.voxygen_i18n,
@@ -1850,8 +1901,8 @@ impl Hud {
             Some(stats),
             Some(loadout),
             Some(energy),
-            Some(character_state),
-            Some(controller),
+            Some(_character_state),
+            Some(_controller),
             Some(inventory),
         ) = (
             stats.get(entity),
@@ -2018,6 +2069,9 @@ impl Hud {
                     settings_window::Event::ToggleZoomInvert(zoom_inverted) => {
                         events.push(Event::ToggleZoomInvert(zoom_inverted));
                     },
+                    settings_window::Event::BuffPosition(buff_position) => {
+                        events.push(Event::BuffPosition(buff_position));
+                    },
                     settings_window::Event::ToggleMouseYInvert(mouse_y_inverted) => {
                         events.push(Event::ToggleMouseYInvert(mouse_y_inverted));
                     },
@@ -2142,27 +2196,6 @@ impl Hud {
                 }
             }
         }
-        // Group Window
-        for event in Group::new(
-            &mut self.show,
-            client,
-            &global_state.settings,
-            &self.imgs,
-            &self.fonts,
-            &self.voxygen_i18n,
-            self.pulse,
-            &global_state,
-        )
-        .set(self.ids.group_window, ui_widgets)
-        {
-            match event {
-                group::Event::Accept => events.push(Event::AcceptInvite),
-                group::Event::Decline => events.push(Event::DeclineInvite),
-                group::Event::Kick(uid) => events.push(Event::KickMember(uid)),
-                group::Event::LeaveGroup => events.push(Event::LeaveGroup),
-                group::Event::AssignLeader(uid) => events.push(Event::AssignLeader(uid)),
-            }
-        }
 
         // Spellbook
         if self.show.spell {
@@ -2694,3 +2727,17 @@ pub fn get_quality_col<I: ItemDesc>(item: &I) -> Color {
         Quality::Debug => QUALITY_DEBUG,
     }
 }
+// Get info about applied buffs
+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(10e6 as f32),
+    }
+}
diff --git a/voxygen/src/hud/overhead.rs b/voxygen/src/hud/overhead.rs
index e24e4eb853..8ee435ea1f 100644
--- a/voxygen/src/hud/overhead.rs
+++ b/voxygen/src/hud/overhead.rs
@@ -3,16 +3,19 @@ use super::{
     REGION_COLOR, SAY_COLOR, STAMINA_COLOR, TELL_COLOR, TEXT_BG, TEXT_COLOR,
 };
 use crate::{
+    hud::{get_buff_info, BuffInfo},
     i18n::VoxygenLocalization,
     settings::GameplaySettings,
     ui::{fonts::ConrodVoxygenFonts, Ingameable},
 };
-use common::comp::{Energy, SpeechBubble, SpeechBubbleType, Stats};
+use common::comp::{BuffId, Buffs, Energy, SpeechBubble, SpeechBubbleType, Stats};
 use conrod_core::{
+    color,
     position::Align,
     widget::{self, Image, Rectangle, Text},
     widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
 };
+use inline_tweak::*;
 const MAX_BUBBLE_WIDTH: f64 = 250.0;
 
 widget_ids! {
@@ -44,13 +47,24 @@ widget_ids! {
         health_txt,
         mana_bar,
         health_bar_fg,
+
+        // Buffs
+        buffs_align,
+        buffs[],
+        buff_timers[],
     }
 }
 
+/*pub struct BuffInfo {
+    id: comp::BuffId,
+    dur: f32,
+}*/
+
 #[derive(Clone, Copy)]
 pub struct Info<'a> {
     pub name: &'a str,
     pub stats: &'a Stats,
+    pub buffs: &'a Buffs,
     pub energy: Option<&'a Energy>,
 }
 
@@ -119,17 +133,21 @@ impl<'a> Ingameable for Overhead<'a> {
         // - 1 for HP text
         // - If there's mana
         //   - 1 Rect::new for mana
-        //
+        // If there are Buffs
+        // - 1 Alignment Rectangle
+        // - 10 + 10 Buffs and Timer Overlays
         // If there's a speech bubble
         // - 2 Text::new for speech bubble
         // - 1 Image::new for icon
         // - 10 Image::new for speech bubble (9-slice + tail)
         self.info.map_or(0, |info| {
-            2 + if show_healthbar(info.stats) {
-                5 + if info.energy.is_some() { 1 } else { 0 }
-            } else {
-                0
-            }
+            2 + 1
+                + info.buffs.active_buffs.len().min(10) * 2
+                + if show_healthbar(info.stats) {
+                    5 + if info.energy.is_some() { 1 } else { 0 }
+                } else {
+                    0
+                }
         }) + if self.bubble.is_some() { 13 } else { 0 }
     }
 }
@@ -155,6 +173,7 @@ impl<'a> Widget for Overhead<'a> {
         if let Some(Info {
             name,
             stats,
+            buffs,
             energy,
         }) = self.info
         {
@@ -172,6 +191,11 @@ impl<'a> Widget for Overhead<'a> {
             } else {
                 MANA_BAR_Y + 32.0
             };
+            let mut buffs_vec = Vec::<BuffInfo>::new();
+            for buff in buffs.active_buffs.clone() {
+                let info = get_buff_info(buff);
+                buffs_vec.push(info);
+            }
             let font_size = if hp_percentage.abs() > 99.9 { 24 } else { 20 };
             // Show K for numbers above 10^3 and truncate them
             // Show M for numbers above 10^6 and truncate them
@@ -185,6 +209,79 @@ impl<'a> Widget for Overhead<'a> {
                 1000..=999999 => format!("{:.0}K", (health_max / 1000.0).max(1.0)),
                 _ => format!("{:.0}M", (health_max as f64 / 1.0e6).max(1.0)),
             };
+            // Buffs
+            // Alignment
+            Rectangle::fill_with([tweak!(168.0), tweak!(100.0)], color::TRANSPARENT)
+                .x_y(-1.0, name_y + tweak!(60.0))
+                .parent(id)
+                .set(state.ids.buffs_align, ui);
+            if state.ids.buffs.len() < buffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .buffs
+                        .resize(buffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            if state.ids.buff_timers.len() < buffs_vec.len() {
+                state.update(|state| {
+                    state
+                        .ids
+                        .buff_timers
+                        .resize(buffs_vec.len(), &mut ui.widget_id_generator())
+                });
+            };
+            let buff_ani = ((self.pulse * 4.0).cos() * 0.5 + 0.8) + 0.5; //Animation timer
+            let pulsating_col = Color::Rgba(1.0, 1.0, 1.0, buff_ani);
+            let norm_col = Color::Rgba(1.0, 1.0, 1.0, 1.0);
+            // Create Buff Widgets
+            for (i, buff) in buffs_vec.iter().enumerate() {
+                if i < 11 && self.bubble.is_none() {
+                    // Limit displayed buffs
+                    let max_duration = match buff.id {
+                        BuffId::Regeneration { duration, .. } => duration.unwrap().as_secs_f32(),
+                        _ => 10.0,
+                    };
+                    let current_duration = buff.dur;
+                    let duration_percentage = (current_duration / max_duration * 1000.0) as u32; // Percentage to determine which frame of the timer overlay is displayed
+                    let buff_img = match buff.id {
+                        BuffId::Regeneration { .. } => self.imgs.buff_plus_0,
+                        BuffId::Bleeding { .. } => self.imgs.debuff_bleed_0,
+                        BuffId::Cursed { .. } => self.imgs.debuff_skull_0,
+                    };
+                    let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
+                    // Sort buffs into rows of 5 slots
+                    let x = i % 5;
+                    let y = i / 5;
+                    let buff_widget = buff_widget.bottom_left_with_margins_on(
+                        state.ids.buffs_align,
+                        0.0 + y as f64 * (21.0),
+                        0.0 + x as f64 * (21.0),
+                    );
+                    buff_widget
+                        .color(if current_duration < 10.0 {
+                            Some(pulsating_col)
+                        } else {
+                            Some(norm_col)
+                        })
+                        .set(state.ids.buffs[i], ui);
+
+                    Image::new(match duration_percentage as u64 {
+                        875..=1000 => self.imgs.nothing, // 8/8
+                        750..=874 => self.imgs.buff_0,   // 7/8
+                        625..=749 => self.imgs.buff_1,   // 6/8
+                        500..=624 => self.imgs.buff_2,   // 5/8
+                        375..=499 => self.imgs.buff_3,   // 4/8
+                        250..=374 => self.imgs.buff_4,   //3/8
+                        125..=249 => self.imgs.buff_5,   // 2/8
+                        0..=124 => self.imgs.buff_6,     // 1/8
+                        _ => self.imgs.nothing,
+                    })
+                    .w_h(20.0, 20.0)
+                    .middle_of(state.ids.buffs[i])
+                    .set(state.ids.buff_timers[i], ui);
+                };
+            }
             // Name
             Text::new(name)
                 .font_id(self.fonts.cyri.conrod_id)
diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs
index 9bf18b9473..b2975c7d52 100644
--- a/voxygen/src/hud/settings_window.rs
+++ b/voxygen/src/hud/settings_window.rs
@@ -4,6 +4,7 @@ use super::{
     TEXT_BIND_CONFLICT_COLOR, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
 };
 use crate::{
+    hud::BuffPosition,
     i18n::{list_localizations, LanguageMetadata, VoxygenLocalization},
     render::{AaMode, CloudMode, FluidMode, LightingMode, RenderMode, ShadowMapMode, ShadowMode},
     ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
@@ -159,6 +160,7 @@ widget_ids! {
         sfx_volume_text,
         audio_device_list,
         audio_device_text,
+        //
         hotbar_title,
         bar_numbers_title,
         show_bar_numbers_none_button,
@@ -167,18 +169,20 @@ widget_ids! {
         show_bar_numbers_values_text,
         show_bar_numbers_percentage_button,
         show_bar_numbers_percentage_text,
+        //
         show_shortcuts_button,
         show_shortcuts_text,
-        show_xpbar_button,
-        show_xpbar_text,
-        show_bars_button,
-        show_bars_text,
-        placeholder,
+        buff_pos_bar_button,
+        buff_pos_bar_text,
+        buff_pos_map_button,
+        buff_pos_map_text,
+        //
         chat_transp_title,
         chat_transp_text,
         chat_transp_slider,
         chat_char_name_text,
         chat_char_name_button,
+        //
         sct_title,
         sct_show_text,
         sct_show_radio,
@@ -195,6 +199,7 @@ widget_ids! {
         sct_num_dur_text,
         sct_num_dur_slider,
         sct_num_dur_value,
+        //
         speech_bubble_text,
         speech_bubble_dark_mode_text,
         speech_bubble_dark_mode_button,
@@ -261,6 +266,7 @@ pub enum Event {
     ToggleTips(bool),
     ToggleBarNumbers(BarNumbers),
     ToggleShortcutNumbers(ShortcutNumbers),
+    BuffPosition(BuffPosition),
     ChangeTab(SettingsTab),
     Close,
     AdjustMousePan(u32),
@@ -829,11 +835,61 @@ impl<'a> Widget for SettingsWindow<'a> {
                 .graphics_for(state.ids.show_shortcuts_button)
                 .color(TEXT_COLOR)
                 .set(state.ids.show_shortcuts_text, ui);
-
-            Rectangle::fill_with([60.0 * 4.0, 1.0 * 4.0], color::TRANSPARENT)
-                .down_from(state.ids.show_shortcuts_text, 30.0)
-                .set(state.ids.placeholder, ui);
-
+            // Buff Position
+            // Buffs above skills
+            if Button::image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Bar => self.imgs.checkbox_checked,
+                BuffPosition::Map => self.imgs.checkbox,
+            })
+            .w_h(18.0, 18.0)
+            .hover_image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Bar => self.imgs.checkbox_checked_mo,
+                BuffPosition::Map => self.imgs.checkbox_mo,
+            })
+            .press_image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Bar => self.imgs.checkbox_checked,
+                BuffPosition::Map => self.imgs.checkbox_press,
+            })
+            .down_from(state.ids.show_shortcuts_button, 8.0)
+            .set(state.ids.buff_pos_bar_button, ui)
+            .was_clicked()
+            {
+                events.push(Event::BuffPosition(BuffPosition::Bar))
+            }
+            Text::new(&self.localized_strings.get("hud.settings.buffs_skillbar"))
+                .right_from(state.ids.buff_pos_bar_button, 10.0)
+                .font_size(self.fonts.cyri.scale(14))
+                .font_id(self.fonts.cyri.conrod_id)
+                .graphics_for(state.ids.show_shortcuts_button)
+                .color(TEXT_COLOR)
+                .set(state.ids.buff_pos_bar_text, ui);
+            // Buffs left from minimap
+            if Button::image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Map => self.imgs.checkbox_checked,
+                BuffPosition::Bar => self.imgs.checkbox,
+            })
+            .w_h(18.0, 18.0)
+            .hover_image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Map => self.imgs.checkbox_checked_mo,
+                BuffPosition::Bar => self.imgs.checkbox_mo,
+            })
+            .press_image(match self.global_state.settings.gameplay.buff_position {
+                BuffPosition::Map => self.imgs.checkbox_checked,
+                BuffPosition::Bar => self.imgs.checkbox_press,
+            })
+            .down_from(state.ids.buff_pos_bar_button, 8.0)
+            .set(state.ids.buff_pos_map_button, ui)
+            .was_clicked()
+            {
+                events.push(Event::BuffPosition(BuffPosition::Map))
+            }
+            Text::new(&self.localized_strings.get("hud.settings.buffs_mmap"))
+                .right_from(state.ids.buff_pos_map_button, 10.0)
+                .font_size(self.fonts.cyri.scale(14))
+                .font_id(self.fonts.cyri.conrod_id)
+                .graphics_for(state.ids.show_shortcuts_button)
+                .color(TEXT_COLOR)
+                .set(state.ids.buff_pos_map_text, ui);
             // Content Right Side
 
             /*Scrolling Combat text
diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs
index 9d752aeed3..d0b3d3a8c9 100644
--- a/voxygen/src/session.rs
+++ b/voxygen/src/session.rs
@@ -894,6 +894,10 @@ impl PlayState for SessionState {
                         global_state.settings.gameplay.shortcut_numbers = shortcut_numbers;
                         global_state.settings.save_to_file_warn();
                     },
+                    HudEvent::BuffPosition(buff_position) => {
+                        global_state.settings.gameplay.buff_position = buff_position;
+                        global_state.settings.save_to_file_warn();
+                    },
                     HudEvent::UiScale(scale_change) => {
                         global_state.settings.gameplay.ui_scale =
                             self.hud.scale_change(scale_change);
@@ -921,6 +925,10 @@ impl PlayState for SessionState {
                         global_state.settings.graphics.max_fps = fps;
                         global_state.settings.save_to_file_warn();
                     },
+                    HudEvent::RemoveBuff(buff_id) => {
+                        let mut client = self.client.borrow_mut();
+                        client.remove_buff(buff_id);
+                    },
                     HudEvent::UseSlot(x) => self.client.borrow_mut().use_slot(x),
                     HudEvent::SwapSlots(a, b) => self.client.borrow_mut().swap_slots(a, b),
                     HudEvent::DropSlot(x) => {
diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs
index be4eed60db..8b4396a094 100644
--- a/voxygen/src/settings.rs
+++ b/voxygen/src/settings.rs
@@ -1,5 +1,5 @@
 use crate::{
-    hud::{BarNumbers, CrosshairType, Intro, PressBehavior, ShortcutNumbers, XpBar},
+    hud::{BarNumbers, BuffPosition, CrosshairType, Intro, PressBehavior, ShortcutNumbers, XpBar},
     i18n,
     render::RenderMode,
     ui::ScaleMode,
@@ -507,6 +507,7 @@ pub struct GameplaySettings {
     pub intro_show: Intro,
     pub xp_bar: XpBar,
     pub shortcut_numbers: ShortcutNumbers,
+    pub buff_position: BuffPosition,
     pub bar_numbers: BarNumbers,
     pub ui_scale: ScaleMode,
     pub free_look_behavior: PressBehavior,
@@ -537,6 +538,7 @@ impl Default for GameplaySettings {
             intro_show: Intro::Show,
             xp_bar: XpBar::Always,
             shortcut_numbers: ShortcutNumbers::On,
+            buff_position: BuffPosition::Bar,
             bar_numbers: BarNumbers::Values,
             ui_scale: ScaleMode::RelativeToWindow([1920.0, 1080.0].into()),
             free_look_behavior: PressBehavior::Toggle,