diff --git a/osu-resources b/osu-resources
index f85c594c18..00406e13d1 160000
--- a/osu-resources
+++ b/osu-resources
@@ -1 +1 @@
-Subproject commit f85c594c182db2b01233e29ca52639b7baa00402
+Subproject commit 00406e13d1b15683b3565a126e207b08bca7555f
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
new file mode 100644
index 0000000000..ebe3800af4
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
@@ -0,0 +1,63 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Screens.Testing;
+using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+    internal class TestCaseTaikoHitObjects : TestCase
+    {
+        public override string Description => "Taiko hit objects";
+
+        public override void Reset()
+        {
+            base.Reset();
+
+            Add(new CentreHitCirclePiece
+            {
+                Position = new Vector2(100, 100)
+            });
+
+            Add(new FinisherPiece(new CentreHitCirclePiece())
+            {
+                Position = new Vector2(350, 100)
+            });
+
+            Add(new RimHitCirclePiece
+            {
+                Position = new Vector2(100, 300)
+            });
+
+            Add(new FinisherPiece(new RimHitCirclePiece())
+            {
+                Position = new Vector2(350, 300)
+            });
+
+            Add(new BashCirclePiece
+            {
+                Position = new Vector2(100, 500)
+            });
+
+            Add(new FinisherPiece(new BashCirclePiece())
+            {
+                Position = new Vector2(350, 500)
+            });
+
+            Add(new DrumRollCirclePiece
+            {
+                Width = 250,
+                Position = new Vector2(575, 100)
+            });
+
+            Add(new FinisherPiece(new DrumRollCirclePiece()
+            {
+                Width = 250
+            })
+            {
+                Position = new Vector2(575, 300)
+            });
+        }
+    }
+}
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index 68aed38b34..28ca0655cc 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -23,7 +23,7 @@
     <SignAssembly>false</SignAssembly>
     <TargetZone>LocalIntranet</TargetZone>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> 
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
     <InstallFrom>Disk</InstallFrom>
@@ -194,6 +194,7 @@
     <Compile Include="Tests\TestCaseReplay.cs" />
     <Compile Include="Tests\TestCaseScoreCounter.cs" />
     <Compile Include="Tests\TestCaseTabControl.cs" />
+    <Compile Include="Tests\TestCaseTaikoHitObjects.cs" />
     <Compile Include="Tests\TestCaseTextAwesome.cs" />
     <Compile Include="Tests\TestCasePlaySongSelect.cs" />
     <Compile Include="Tests\TestCaseTwoLayerButton.cs" />
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs
new file mode 100644
index 0000000000..8298c5a871
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/BashCirclePiece.cs
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
+using osu.Game.Graphics;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A circle piece which is used to visualise Bash objects.
+    /// </summary>
+    public class BashCirclePiece : CirclePiece
+    {
+        private Sprite icon;
+
+        [BackgroundDependencyLoader]
+        private void load(OsuColour colours, TextureStore textures)
+        {
+            AccentColour = colours.YellowDark;
+
+            icon.Texture = textures.Get(@"Play/Taiko/bash-hit-inner");
+        }
+
+        protected override Framework.Graphics.Drawable CreateIcon()
+        {
+            return icon = new Sprite
+            {
+                Anchor = Anchor.Centre,
+                Origin = Anchor.Centre,
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs
new file mode 100644
index 0000000000..922e377ef5
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CentreHitCirclePiece.cs
@@ -0,0 +1,45 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics;
+using OpenTK;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A circle piece which is used to visualise CentreHit objects.
+    /// </summary>
+    public class CentreHitCirclePiece : CirclePiece
+    {
+        [BackgroundDependencyLoader]
+        private void load(OsuColour colours)
+        {
+            AccentColour = colours.PinkDarker;
+        }
+
+        protected override Framework.Graphics.Drawable CreateIcon()
+        {
+            return new CircularContainer
+            {
+                Anchor = Anchor.Centre,
+                Origin = Anchor.Centre,
+
+                Size = new Vector2(45f),
+
+                Children = new[]
+                {
+                    new Box
+                    {
+                        RelativeSizeAxes = Axes.Both,
+
+                        Alpha = 1
+                    }
+                }
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs
new file mode 100644
index 0000000000..20971cb84d
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/CirclePiece.cs
@@ -0,0 +1,204 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics.Backgrounds;
+using OpenTK.Graphics;
+using OpenTK;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A circle piece which is used uniformly through osu!taiko to visualise hitobjects.
+    /// <para>
+    /// The body of this piece will overshoot it by Height/2 on both sides of its length, such that
+    /// a regular "circle" the result of setting Width to 0.
+    /// </para>
+    /// <para>
+    /// Hitobjects that have a length need only to set Width and the extra corner radius will be added internally.
+    /// </para>
+    /// </summary>
+    public abstract class CirclePiece : ScrollingCirclePiece
+    {
+        /// <summary>
+        /// The colour of the inner circle and outer glows.
+        /// </summary>
+        public Color4 AccentColour { get; protected set; }
+
+        private bool kiaiMode;
+        /// <summary>
+        /// Whether Kiai mode is active for this object.
+        /// </summary>
+        public bool KiaiMode
+        {
+            get { return kiaiMode; }
+            set
+            {
+                kiaiMode = value;
+
+                if (innerCircleContainer != null)
+                    innerCircleContainer.EdgeEffect = value ? createKiaiEdgeEffect() : default(EdgeEffect);
+            }
+        }
+
+        public override Vector2 Size => new Vector2(base.Size.X, 128);
+
+        private Container innerLayer;
+        private Container backingGlowContainer;
+        private Container innerCircleContainer;
+        private Box innerBackground;
+        private Triangles triangles;
+
+        protected CirclePiece()
+        {
+            Container iconContainer;
+
+            Children = new Framework.Graphics.Drawable[]
+            {
+                // The "inner layer" overshoots the ObjectPiece by 64px on both sides
+                innerLayer = new Container
+                {
+                    Name = "Inner Layer",
+
+                    Anchor = Anchor.Centre,
+                    Origin = Anchor.Centre,
+
+                    RelativeSizeAxes = Axes.Y,
+
+                    Children = new Framework.Graphics.Drawable[]
+                    {
+                        backingGlowContainer = new CircularContainer
+                        {
+                            Name = "Backing Glow",
+
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+
+                            RelativeSizeAxes = Axes.Both,
+
+                            Children = new[]
+                            {
+                                new Box
+                                {
+                                    RelativeSizeAxes = Axes.Both,
+
+                                    Alpha = 0,
+                                    AlwaysPresent = true
+                                }
+                            }
+                        },
+                        innerCircleContainer = new CircularContainer
+                        {
+                            Name = "Inner Circle",
+
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+
+                            RelativeSizeAxes = Axes.Both,
+
+                            Children = new Framework.Graphics.Drawable[]
+                            {
+                                innerBackground = new Box
+                                {
+                                    Anchor = Anchor.Centre,
+                                    Origin = Anchor.Centre,
+
+                                    RelativeSizeAxes = Axes.Both,
+                                },
+                                triangles = new Triangles
+                                {
+                                    Anchor = Anchor.Centre,
+                                    Origin = Anchor.Centre,
+
+                                    RelativeSizeAxes = Axes.Both,
+                                }
+                            }
+                        },
+                        new CircularContainer
+                        {
+                            Name = "Ring",
+
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+
+                            RelativeSizeAxes = Axes.Both,
+
+                            BorderThickness = 8,
+                            BorderColour = Color4.White,
+
+                            Children = new[]
+                            {
+                                new Box
+                                {
+                                    Anchor = Anchor.Centre,
+                                    Origin = Anchor.Centre,
+
+                                    RelativeSizeAxes = Axes.Both,
+
+                                    Alpha = 0,
+                                    AlwaysPresent = true
+                                }
+                            }
+                        },
+                        iconContainer = new Container
+                        {
+                            Name = "Icon Container",
+
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+                        }
+                    }
+                },
+            };
+
+            Framework.Graphics.Drawable icon = CreateIcon();
+
+            if (icon != null)
+                iconContainer.Add(icon);
+        }
+
+        protected override void LoadComplete()
+        {
+            base.LoadComplete();
+
+            backingGlowContainer.EdgeEffect = new EdgeEffect
+            {
+                Type = EdgeEffectType.Glow,
+                Colour = AccentColour,
+                Radius = 8
+            };
+
+            if (KiaiMode)
+                innerCircleContainer.EdgeEffect = createKiaiEdgeEffect();
+
+            innerBackground.Colour = AccentColour;
+
+            triangles.ColourLight = AccentColour;
+            triangles.ColourDark = AccentColour.Darken(0.1f);
+        }
+
+        protected override void Update()
+        {
+            innerLayer.Width = DrawWidth + DrawHeight;
+        }
+
+        private EdgeEffect createKiaiEdgeEffect()
+        {
+            return new EdgeEffect
+            {
+                Type = EdgeEffectType.Glow,
+                Colour = AccentColour,
+                Radius = 50
+            };
+        }
+
+        /// <summary>
+        /// Creates the icon that's shown in the middle of this object piece.
+        /// </summary>
+        /// <returns>The icon.</returns>
+        protected virtual Framework.Graphics.Drawable CreateIcon() => null;
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs
new file mode 100644
index 0000000000..fea538d654
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/DrumRollCirclePiece.cs
@@ -0,0 +1,20 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Game.Graphics;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A circle piece which is used to visualise DrumRoll objects.
+    /// </summary>
+    public class DrumRollCirclePiece : CirclePiece
+    {
+        [BackgroundDependencyLoader]
+        private void load(OsuColour colours)
+        {
+            AccentColour = colours.YellowDark;
+        }
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs
new file mode 100644
index 0000000000..699bac0bd0
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/FinisherPiece.cs
@@ -0,0 +1,31 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A type of circle piece that encapsulates a circle piece to visualise it as a "finisher" hitobject.
+    /// <para>
+    /// Finisher hitobjects are 1.5x larger, while maintaining the same length.
+    /// </para>
+    /// </summary>
+    public class FinisherPiece : ScrollingCirclePiece
+    {
+        public FinisherPiece(ScrollingCirclePiece original)
+        {
+            // First we scale the note up
+            Scale = new Vector2(1.5f);
+
+            Children = new[]
+            {
+                original
+            };
+
+            // Next we reduce the draw width for drum rolls to keep the width
+            // equal to that of a non-finisher drum roll
+            original.Width /= 1.5f;
+        }
+    }
+}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs
new file mode 100644
index 0000000000..5f1c767063
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/RimHitCirclePiece.cs
@@ -0,0 +1,50 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics;
+using OpenTK;
+using OpenTK.Graphics;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A circle piece which is used to visualise RimHit objects.
+    /// </summary>
+    public class RimHitCirclePiece : CirclePiece
+    {
+        [BackgroundDependencyLoader]
+        private void load(OsuColour colours)
+        {
+            AccentColour = colours.BlueDarker;
+        }
+
+        protected override Framework.Graphics.Drawable CreateIcon()
+        {
+            return new CircularContainer
+            {
+                Anchor = Anchor.Centre,
+                Origin = Anchor.Centre,
+
+                Size = new Vector2(61f),
+
+                BorderThickness = 8,
+                BorderColour = Color4.White,
+
+                Children = new[]
+                {
+                    new Box
+                    {
+                        RelativeSizeAxes = Axes.Both,
+
+                        Alpha = 0,
+                        AlwaysPresent = true
+                    }
+                }
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs
new file mode 100644
index 0000000000..413fc55e80
--- /dev/null
+++ b/osu.Game.Modes.Taiko/Objects/Drawable/Pieces/ScrollingCirclePiece.cs
@@ -0,0 +1,19 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+
+namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
+{
+    /// <summary>
+    /// A type of circle piece that will be scrolling the screen.
+    /// <para>
+    /// A scrolling circle piece must always have a centre-left origin due to how scroll position is calculated.
+    /// </para>
+    /// </summary>
+    public class ScrollingCirclePiece : Container
+    {
+        public override Anchor Origin => Anchor.CentreLeft;
+    }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
index 7ea6dfeadb..81fb35be60 100644
--- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
+++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
@@ -50,6 +50,13 @@
     <Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
     <Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" />
     <Compile Include="Judgements\TaikoJudgementInfo.cs" />
+    <Compile Include="Objects\Drawable\Pieces\BashCirclePiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\CentreHitCirclePiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\CirclePiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\DrumRollCirclePiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\FinisherPiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\RimHitCirclePiece.cs" />
+    <Compile Include="Objects\Drawable\Pieces\ScrollingCirclePiece.cs" />
     <Compile Include="TaikoDifficultyCalculator.cs" />
     <Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
     <Compile Include="Objects\TaikoHitObject.cs" />
@@ -81,6 +88,7 @@
       <Name>osu.Game</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.