From 5352da277d3cf46b3997d426b92ad8cb2510e4de Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 08:16:19 +0930
Subject: [PATCH 01/19] Remove ScaleFixContainer.

---
 osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 214 +++++++------------
 1 file changed, 78 insertions(+), 136 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index b0fb9d7f28..1f83e36c14 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -56,111 +56,104 @@ namespace osu.Game.Rulesets.Taiko.UI
         {
             AddRangeInternal(new Drawable[]
             {
-                new ScaleFixContainer
+                backgroundContainer = new Container
                 {
-                    RelativeSizeAxes = Axes.X,
-                    Height = DEFAULT_PLAYFIELD_HEIGHT,
-                    Children = new[]
+                    Name = "Transparent playfield background",
+                    RelativeSizeAxes = Axes.Both,
+                    BorderThickness = 2,
+                    Masking = true,
+                    EdgeEffect = new EdgeEffectParameters
                     {
-                        backgroundContainer = new Container
+                        Type = EdgeEffectType.Shadow,
+                        Colour = Color4.Black.Opacity(0.2f),
+                        Radius = 5,
+                    },
+                    Children = new Drawable[]
+                    {
+                        background = new Box
                         {
-                            Name = "Transparent playfield background",
                             RelativeSizeAxes = Axes.Both,
-                            BorderThickness = 2,
-                            Masking = true,
-                            EdgeEffect = new EdgeEffectParameters
-                            {
-                                Type = EdgeEffectType.Shadow,
-                                Colour = Color4.Black.Opacity(0.2f),
-                                Radius = 5,
-                            },
-                            Children = new Drawable[]
-                            {
-                                background = new Box
-                                {
-                                    RelativeSizeAxes = Axes.Both,
-                                    Alpha = 0.6f
-                                },
-                            }
+                            Alpha = 0.6f
                         },
+                    }
+                },
+                new Container
+                {
+                    Name = "Right area",
+                    RelativeSizeAxes = Axes.Both,
+                    Margin = new MarginPadding { Left = left_area_size },
+                    Children = new Drawable[]
+                    {
                         new Container
                         {
-                            Name = "Right area",
+                            Name = "Masked elements",
                             RelativeSizeAxes = Axes.Both,
-                            Margin = new MarginPadding { Left = left_area_size },
+                            Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
+                            Masking = true,
                             Children = new Drawable[]
                             {
-                                new Container
+                                hitExplosionContainer = new Container<HitExplosion>
+                                {
+                                    RelativeSizeAxes = Axes.Y,
+                                    BlendingMode = BlendingMode.Additive,
+                                },
+                                barLineContainer = new Container<DrawableBarLine>
                                 {
-                                    Name = "Masked elements",
                                     RelativeSizeAxes = Axes.Both,
-                                    Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
-                                    Masking = true,
-                                    Children = new Drawable[]
-                                    {
-                                        hitExplosionContainer = new Container<HitExplosion>
-                                        {
-                                            RelativeSizeAxes = Axes.Y,
-                                            BlendingMode = BlendingMode.Additive,
-                                        },
-                                        barLineContainer = new Container<DrawableBarLine>
-                                        {
-                                            RelativeSizeAxes = Axes.Both,
-                                        },
-                                        new HitTarget
-                                        {
-                                            Anchor = Anchor.CentreLeft,
-                                            Origin = Anchor.Centre,
-                                        },
-                                        hitObjectContainer = new Container
-                                        {
-                                            RelativeSizeAxes = Axes.Both,
-                                        },
-                                    }
                                 },
-                                kiaiExplosionContainer = new Container<KiaiHitExplosion>
+                                new HitTarget
                                 {
-                                    Name = "Kiai hit explosions",
-                                    RelativeSizeAxes = Axes.Y,
-                                    Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
-                                    BlendingMode = BlendingMode.Additive
+                                    Anchor = Anchor.CentreLeft,
+                                    Origin = Anchor.Centre,
                                 },
-                                judgementContainer = new Container<DrawableTaikoJudgement>
+                                hitObjectContainer = new Container
                                 {
-                                    Name = "Judgements",
-                                    RelativeSizeAxes = Axes.Y,
-                                    Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
-                                    BlendingMode = BlendingMode.Additive
+                                    RelativeSizeAxes = Axes.Both,
                                 },
                             }
                         },
-                        overlayBackgroundContainer = new Container
+                        kiaiExplosionContainer = new Container<KiaiHitExplosion>
                         {
-                            Name = "Left overlay",
-                            Size = new Vector2(left_area_size, DEFAULT_PLAYFIELD_HEIGHT),
-                            BorderThickness = 1,
-                            Children = new Drawable[]
-                            {
-                                overlayBackground = new Box
-                                {
-                                    RelativeSizeAxes = Axes.Both,
-                                },
-                                new InputDrum
-                                {
-                                    Anchor = Anchor.Centre,
-                                    Origin = Anchor.Centre,
-                                    RelativePositionAxes = Axes.X,
-                                    Position = new Vector2(0.10f, 0),
-                                    Scale = new Vector2(0.9f)
-                                },
-                                new Box
-                                {
-                                    Anchor = Anchor.TopRight,
-                                    RelativeSizeAxes = Axes.Y,
-                                    Width = 10,
-                                    Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
-                                },
-                            }
+                            Name = "Kiai hit explosions",
+                            RelativeSizeAxes = Axes.Y,
+                            Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
+                            BlendingMode = BlendingMode.Additive
+                        },
+                        judgementContainer = new Container<DrawableTaikoJudgement>
+                        {
+                            Name = "Judgements",
+                            RelativeSizeAxes = Axes.Y,
+                            Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
+                            BlendingMode = BlendingMode.Additive
+                        },
+                    }
+                },
+                overlayBackgroundContainer = new Container
+                {
+                    Name = "Left overlay",
+                    RelativeSizeAxes = Axes.Y,
+                    Size = new Vector2(left_area_size, 1),
+                    BorderThickness = 1,
+                    Children = new Drawable[]
+                    {
+                        overlayBackground = new Box
+                        {
+                            RelativeSizeAxes = Axes.Both,
+                        },
+                        new InputDrum
+                        {
+                            Anchor = Anchor.Centre,
+                            Origin = Anchor.Centre,
+                            RelativePositionAxes = Axes.X,
+                            Position = new Vector2(0.10f, 0),
+                            Scale = new Vector2(0.9f)
+                        },
+                        new Box
+                        {
+                            Anchor = Anchor.TopRight,
+                            RelativeSizeAxes = Axes.Y,
+                            Width = 10,
+                            Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
                         },
                     }
                 },
@@ -233,56 +226,5 @@ namespace osu.Game.Rulesets.Taiko.UI
             else
                 hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
         }
-
-        /// <summary>
-        /// This is a very special type of container. It serves a similar purpose to <see cref="FillMode.Fit"/>, however unlike <see cref="FillMode.Fit"/>,
-        /// this will only adjust the scale relative to the height of its parent and will maintain the original width relative to its parent.
-        ///
-        /// <para>
-        /// By adjusting the scale relative to the height of its parent, the aspect ratio of this container's children is maintained, however this is undesirable
-        /// in the case where the hit object container should not have its width adjusted by scale. To counteract this, another container is nested inside this
-        /// container which takes care of reversing the width adjustment while appearing transparent to the user.
-        /// </para>
-        /// </summary>
-        private class ScaleFixContainer : Container
-        {
-            protected override Container<Drawable> Content => widthAdjustmentContainer;
-            private readonly WidthAdjustmentContainer widthAdjustmentContainer;
-
-            /// <summary>
-            /// We only want to apply DrawScale in the Y-axis to preserve aspect ratio and <see cref="TaikoPlayfield"/> doesn't care about having its width adjusted.
-            /// </summary>
-            protected override Vector2 DrawScale => Scale * RelativeToAbsoluteFactor.Y / DrawHeight;
-
-            public ScaleFixContainer()
-            {
-                AddInternal(widthAdjustmentContainer = new WidthAdjustmentContainer { ParentDrawScaleReference = () => DrawScale.X });
-            }
-
-            /// <summary>
-            /// The container type that reverses the <see cref="Drawable.DrawScale"/> width adjustment.
-            /// </summary>
-            private class WidthAdjustmentContainer : Container
-            {
-                /// <summary>
-                /// This container needs to know its parent's <see cref="Drawable.DrawScale"/> so it can reverse the width adjustment caused by <see cref="Drawable.DrawScale"/>.
-                /// </summary>
-                public Func<float> ParentDrawScaleReference;
-
-                public WidthAdjustmentContainer()
-                {
-                    // This container doesn't care about height, it should always fill its parent
-                    RelativeSizeAxes = Axes.Y;
-                }
-
-                protected override void Update()
-                {
-                    base.Update();
-
-                    // Reverse the DrawScale adjustment
-                    Width = Parent.DrawSize.X / ParentDrawScaleReference();
-                }
-            }
-        }
     }
 }
\ No newline at end of file

From 358b7c9d3d5ce2d9f1c71aa7004018acf33e93d7 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 08:19:25 +0930
Subject: [PATCH 02/19] Better InputDrum sizing + positioning.

---
 osu.Game.Rulesets.Taiko/UI/InputDrum.cs      | 8 +++++---
 osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 9 ++++-----
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index 60881f3c24..0255171284 100644
--- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -21,9 +21,10 @@ namespace osu.Game.Rulesets.Taiko.UI
     {
         public InputDrum()
         {
-            Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
+            RelativeSizeAxes = Axes.Both;
+            FillMode = FillMode.Fit;
 
-            const float middle_split = 10;
+            const float middle_split = 0.025f;
 
             Children = new Drawable[]
             {
@@ -33,6 +34,7 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Anchor = Anchor.Centre,
                     Origin = Anchor.CentreRight,
                     RelativeSizeAxes = Axes.Both,
+                    RelativePositionAxes = Axes.X,
                     X = -middle_split / 2,
                     RimKey = Key.D,
                     CentreKey = Key.F
@@ -43,8 +45,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Anchor = Anchor.Centre,
                     Origin = Anchor.CentreLeft,
                     RelativeSizeAxes = Axes.Both,
+                    RelativePositionAxes = Axes.X,
                     X = middle_split / 2,
-                    Position = new Vector2(-1f, 0),
                     RimKey = Key.K,
                     CentreKey = Key.J
                 }
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index 1f83e36c14..62f4ddd052 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -142,11 +142,10 @@ namespace osu.Game.Rulesets.Taiko.UI
                         },
                         new InputDrum
                         {
-                            Anchor = Anchor.Centre,
-                            Origin = Anchor.Centre,
-                            RelativePositionAxes = Axes.X,
-                            Position = new Vector2(0.10f, 0),
-                            Scale = new Vector2(0.9f)
+                            Anchor = Anchor.CentreRight,
+                            Origin = Anchor.CentreRight,
+                            Scale = new Vector2(0.9f),
+                            Margin = new MarginPadding { Right = 20 }
                         },
                         new Box
                         {

From 13af804bbba669cfcfdf6d04bdc225d7475c52df Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:11:53 +0930
Subject: [PATCH 03/19] Fix TestCaseTaikoPlayfield not correctly setting strong
 hit objects.

---
 osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 8ca129eb91..1faeb7dc35 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -18,7 +18,7 @@ namespace osu.Desktop.VisualTests.Tests
 {
     internal class TestCaseTaikoPlayfield : TestCase
     {
-        private const double default_duration = 300;
+        private const double default_duration = 1000;
         private const float scroll_time = 1000;
 
         public override string Description => "Taiko playfield";
@@ -180,7 +180,8 @@ namespace osu.Desktop.VisualTests.Tests
             Hit h = new Hit
             {
                 StartTime = playfield.Time.Current + scroll_time,
-                ScrollTime = scroll_time
+                ScrollTime = scroll_time,
+                IsStrong = strong
             };
 
             if (strong)
@@ -194,7 +195,8 @@ namespace osu.Desktop.VisualTests.Tests
             Hit h = new Hit
             {
                 StartTime = playfield.Time.Current + scroll_time,
-                ScrollTime = scroll_time
+                ScrollTime = scroll_time,
+                IsStrong = strong
             };
 
             if (strong)

From 17cad7605492370f31a07a46d43a1426eeb95583 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:33:46 +0930
Subject: [PATCH 04/19] Make TestCaseTaikoPlayfield able to visualise kiai
 hits.

---
 .../Tests/TestCaseTaikoPlayfield.cs            | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 1faeb7dc35..f5cc7f3120 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -13,6 +13,8 @@ using osu.Game.Rulesets.Taiko.Objects;
 using osu.Game.Rulesets.Taiko.Objects.Drawables;
 using osu.Game.Rulesets.Taiko.UI;
 using System;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Beatmaps;
 
 namespace osu.Desktop.VisualTests.Tests
 {
@@ -31,7 +33,8 @@ namespace osu.Desktop.VisualTests.Tests
 
         public TestCaseTaikoPlayfield()
         {
-            AddStep("Hit!", addHitJudgement);
+            AddStep("Hit!", () => addHitJudgement(false));
+            AddStep("Kiai hit", () => addHitJudgement(true));
             AddStep("Miss :(", addMissJudgement);
             AddStep("DrumRoll", () => addDrumRoll(false));
             AddStep("Strong DrumRoll", () => addDrumRoll(true));
@@ -102,11 +105,20 @@ namespace osu.Desktop.VisualTests.Tests
             }
         }
 
-        private void addHitJudgement()
+        private void addHitJudgement(bool kiai)
         {
             TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;
 
-            var h = new DrawableTestHit(new Hit())
+            var cpi = new ControlPointInfo();
+            cpi.EffectPoints.Add(new EffectControlPoint
+            {
+                KiaiMode = kiai
+            });
+
+            Hit hit = new Hit();
+            hit.ApplyDefaults(cpi, new BeatmapDifficulty());
+
+            var h = new DrawableTestHit(hit)
             {
                 X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
                 Judgement = new TaikoJudgement

From 324fd456a73550febc744411ae79228e2bf51a47 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:35:07 +0930
Subject: [PATCH 05/19] Rework border + fillmodes + size in TaikoPlayfield.

---
 .../Tests/TestCaseTaikoPlayfield.cs           |  4 +--
 .../UI/TaikoHitRenderer.cs                    |  2 +-
 osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs  | 36 ++++++++++++++-----
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index f5cc7f3120..3f4d4e9722 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -59,7 +59,7 @@ namespace osu.Desktop.VisualTests.Tests
                 Anchor = Anchor.Centre,
                 Origin = Anchor.Centre,
                 RelativeSizeAxes = Axes.X,
-                Height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT,
+                Height = TaikoPlayfield.DEFAULT_HEIGHT,
                 Clock = new FramedClock(rateAdjustClock),
                 Children = new[]
                 {
@@ -100,7 +100,7 @@ namespace osu.Desktop.VisualTests.Tests
                     playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
                     break;
                 case 6:
-                    playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT), 500);
+                    playfieldContainer.Delay(delay).ResizeTo(new Vector2(TaikoPlayfield.DEFAULT_HEIGHT), 500);
                     break;
             }
         }
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
index 662cace511..570b4be488 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
@@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Taiko.UI
 
         protected override Vector2 GetPlayfieldAspectAdjust()
         {
-            const float default_relative_height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT / 768;
+            const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
             const float default_aspect = 16f / 9f;
 
             float aspectAdjust = MathHelper.Clamp(DrawWidth / DrawHeight, 0.4f, 4) / default_aspect;
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index 62f4ddd052..fff19b97c9 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Taiko.UI
     public class TaikoPlayfield : Playfield<TaikoHitObject, TaikoJudgement>
     {
         /// <summary>
-        /// The default play field height.
+        /// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoHitRenderer"/>.
         /// </summary>
-        public const float DEFAULT_PLAYFIELD_HEIGHT = 178f;
+        public const float DEFAULT_HEIGHT = 178;
 
         /// <summary>
         /// The offset from <see cref="left_area_size"/> which the center of the hit target lies at.
         /// </summary>
-        public const float HIT_TARGET_OFFSET = TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER / 2f + 40;
+        public const float HIT_TARGET_OFFSET = 100;
 
         /// <summary>
         /// The size of the left area of the playfield. This area contains the input drum.
@@ -60,7 +60,6 @@ namespace osu.Game.Rulesets.Taiko.UI
                 {
                     Name = "Transparent playfield background",
                     RelativeSizeAxes = Axes.Both,
-                    BorderThickness = 2,
                     Masking = true,
                     EdgeEffect = new EdgeEffectParameters
                     {
@@ -81,7 +80,7 @@ namespace osu.Game.Rulesets.Taiko.UI
                 {
                     Name = "Right area",
                     RelativeSizeAxes = Axes.Both,
-                    Margin = new MarginPadding { Left = left_area_size },
+                    Padding = new MarginPadding { Left = left_area_size },
                     Children = new Drawable[]
                     {
                         new Container
@@ -94,7 +93,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                             {
                                 hitExplosionContainer = new Container<HitExplosion>
                                 {
-                                    RelativeSizeAxes = Axes.Y,
+                                    RelativeSizeAxes = Axes.Both,
+                                    FillMode = FillMode.Fit,
                                     BlendingMode = BlendingMode.Additive,
                                 },
                                 barLineContainer = new Container<DrawableBarLine>
@@ -105,6 +105,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                                 {
                                     Anchor = Anchor.CentreLeft,
                                     Origin = Anchor.Centre,
+                                    RelativeSizeAxes = Axes.Both,
+                                    FillMode = FillMode.Fit
                                 },
                                 hitObjectContainer = new Container
                                 {
@@ -115,7 +117,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                         kiaiExplosionContainer = new Container<KiaiHitExplosion>
                         {
                             Name = "Kiai hit explosions",
-                            RelativeSizeAxes = Axes.Y,
+                            RelativeSizeAxes = Axes.Both,
+                            FillMode = FillMode.Fit,
                             Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
                             BlendingMode = BlendingMode.Additive
                         },
@@ -133,7 +136,6 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Name = "Left overlay",
                     RelativeSizeAxes = Axes.Y,
                     Size = new Vector2(left_area_size, 1),
-                    BorderThickness = 1,
                     Children = new Drawable[]
                     {
                         overlayBackground = new Box
@@ -156,6 +158,24 @@ namespace osu.Game.Rulesets.Taiko.UI
                         },
                     }
                 },
+                new Container
+                {
+                    Name = "Border",
+                    RelativeSizeAxes = Axes.Both,
+                    Masking = true,
+                    MaskingSmoothness = 0,
+                    BorderThickness = 2,
+                    AlwaysPresent = true,
+                    Children = new[]
+                    {
+                        new Box
+                        {
+                            RelativeSizeAxes = Axes.Both,
+                            Alpha = 0,
+                            AlwaysPresent = true
+                        }
+                    }
+                },
                 topLevelHitContainer = new Container
                 {
                     Name = "Top level hit objects",

From 22ffc787578b1af7bd5d056b55883bdd44b6a4fa Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:36:04 +0930
Subject: [PATCH 06/19] Rework consts in TaikoHitObject to be relative size
 values.

---
 .../Objects/TaikoHitObject.cs                   | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index db368cb112..5f3223e918 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -11,24 +11,19 @@ namespace osu.Game.Rulesets.Taiko.Objects
     public abstract class TaikoHitObject : HitObject
     {
         /// <summary>
-        /// Diameter of a circle relative to the size of the <see cref="TaikoPlayfield"/>.
+        /// Default size of a <see cref="DrawableTaikoHitObject"/>.
         /// </summary>
-        public const float PLAYFIELD_RELATIVE_DIAMETER = 0.45f;
+        public const float DEFAULT_SIZE = 0.45f;
 
         /// <summary>
-        /// Scale multiplier for a strong circle.
+        /// Scale multiplier for a strong <see cref="DrawableTaikoHitObject"/>.
         /// </summary>
-        public const float STRONG_CIRCLE_DIAMETER_SCALE = 1.4f;
+        public const float STRONG_SCALE = 1.4f;
 
         /// <summary>
-        /// Default circle diameter.
+        /// Default size of a strong <see cref="DrawableTaikoHitObject"/>.
         /// </summary>
-        public const float DEFAULT_CIRCLE_DIAMETER = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT * PLAYFIELD_RELATIVE_DIAMETER;
-
-        /// <summary>
-        /// Default strong circle diameter.
-        /// </summary>
-        public const float DEFAULT_STRONG_CIRCLE_DIAMETER = DEFAULT_CIRCLE_DIAMETER * STRONG_CIRCLE_DIAMETER_SCALE;
+        public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
 
         /// <summary>
         /// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a <see cref="TimingControlPoint.BeatLength"/> of 1000ms.

From d796730e36c34e4893e7c8f35de2d697f2ef058f Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:36:15 +0930
Subject: [PATCH 07/19] Fix KiaiHitExplosion.

---
 osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
index 524490fac3..bac956a25b 100644
--- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
@@ -24,11 +24,11 @@ namespace osu.Game.Rulesets.Taiko.UI
 
             Judgement = judgement;
 
-            Anchor = Anchor.Centre;
+            Anchor = Anchor.CentreLeft;
             Origin = Anchor.Centre;
 
-            RelativeSizeAxes = Axes.Y;
-            Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER, 1);
+            RelativeSizeAxes = Axes.Both;
+            Size = new Vector2(TaikoHitObject.DEFAULT_SIZE, 1);
 
             Masking = true;
             Alpha = 0.25f;

From 14639ff8e37d08cebb0e500db6cf583642a22984 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:36:36 +0930
Subject: [PATCH 08/19] Fix HitTarget.

---
 osu.Game.Rulesets.Taiko/UI/HitTarget.cs | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/UI/HitTarget.cs b/osu.Game.Rulesets.Taiko/UI/HitTarget.cs
index 1ca6e4eb34..8f3b6840f3 100644
--- a/osu.Game.Rulesets.Taiko/UI/HitTarget.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitTarget.cs
@@ -15,11 +15,6 @@ namespace osu.Game.Rulesets.Taiko.UI
     /// </summary>
     internal class HitTarget : Container
     {
-        /// <summary>
-        /// The 1px inner border of the taiko playfield.
-        /// </summary>
-        private const float border_offset = 1;
-
         /// <summary>
         /// Thickness of all drawn line pieces.
         /// </summary>
@@ -27,8 +22,6 @@ namespace osu.Game.Rulesets.Taiko.UI
 
         public HitTarget()
         {
-            Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
-
             Children = new Drawable[]
             {
                 new Box
@@ -36,8 +29,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Name = "Bar Upper",
                     Anchor = Anchor.TopCentre,
                     Origin = Anchor.TopCentre,
-                    Y = border_offset,
-                    Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
+                    RelativeSizeAxes = Axes.Y,
+                    Size = new Vector2(border_thickness, (1 - TaikoHitObject.DEFAULT_STRONG_SIZE) / 2f),
                     Alpha = 0.1f
                 },
                 new CircularContainer
@@ -45,7 +38,9 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Name = "Strong Hit Ring",
                     Anchor = Anchor.Centre,
                     Origin = Anchor.Centre,
-                    Size = new Vector2(TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER),
+                    RelativeSizeAxes = Axes.Both,
+                    FillMode = FillMode.Fit,
+                    Scale = new Vector2(TaikoHitObject.DEFAULT_STRONG_SIZE),
                     Masking = true,
                     BorderColour = Color4.White,
                     BorderThickness = border_thickness,
@@ -65,7 +60,9 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Name = "Normal Hit Ring",
                     Anchor = Anchor.Centre,
                     Origin = Anchor.Centre,
-                    Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
+                    RelativeSizeAxes = Axes.Both,
+                    FillMode = FillMode.Fit,
+                    Scale = new Vector2(TaikoHitObject.DEFAULT_SIZE),
                     Masking = true,
                     BorderColour = Color4.White,
                     BorderThickness = border_thickness,
@@ -85,8 +82,8 @@ namespace osu.Game.Rulesets.Taiko.UI
                     Name = "Bar Lower",
                     Anchor = Anchor.BottomCentre,
                     Origin = Anchor.BottomCentre,
-                    Y = -border_offset,
-                    Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
+                    RelativeSizeAxes = Axes.Y,
+                    Size = new Vector2(border_thickness, (1 - TaikoHitObject.DEFAULT_STRONG_SIZE) / 2f),
                     Alpha = 0.1f
                 },
             };

From b2d69dfa02268d9e56b9090cf84a75cdc96db7aa Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:36:49 +0930
Subject: [PATCH 09/19] Fix HitExplosion.

---
 osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
index c372ac1809..cb849a11c7 100644
--- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
@@ -30,10 +30,11 @@ namespace osu.Game.Rulesets.Taiko.UI
 
             Judgement = judgement;
 
-            Anchor = Anchor.Centre;
+            Anchor = Anchor.CentreLeft;
             Origin = Anchor.Centre;
 
-            Size = new Vector2(TaikoPlayfield.HIT_TARGET_OFFSET + TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
+            RelativeSizeAxes = Axes.Both;
+            Size = new Vector2(TaikoHitObject.DEFAULT_SIZE);
 
             RelativePositionAxes = Axes.Both;
 
@@ -73,7 +74,7 @@ namespace osu.Game.Rulesets.Taiko.UI
         /// </summary>
         public void VisualiseSecondHit()
         {
-            this.ResizeTo(new Vector2(TaikoPlayfield.HIT_TARGET_OFFSET + TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER), 50);
+            this.ResizeTo(new Vector2(TaikoHitObject.DEFAULT_STRONG_SIZE), 50);
         }
     }
 }

From 786bad3d71f4114762831dc093e0147eca3e3e90 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:53:12 +0930
Subject: [PATCH 10/19] Simplify + fix up circle pieces.

---
 .../Drawables/Pieces/CentreHitSymbolPiece.cs  | 10 +++-------
 .../Objects/Drawables/Pieces/CirclePiece.cs   | 19 +++++--------------
 .../Drawables/Pieces/ElongatedCirclePiece.cs  |  4 +++-
 .../Drawables/Pieces/RimHitSymbolPiece.cs     |  2 ++
 .../Drawables/Pieces/SwellSymbolPiece.cs      |  7 ++++++-
 .../Objects/Drawables/Pieces/TaikoPiece.cs    |  6 ++++--
 .../Objects/Drawables/Pieces/TickPiece.cs     |  8 ++++++--
 7 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
index cc88105e03..8ad548b3d6 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
@@ -17,15 +17,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         {
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
+
             Size = new Vector2(CirclePiece.SYMBOL_INNER_SIZE);
             Masking = true;
-            Children = new[]
-            {
-                new Box
-                {
-                    RelativeSizeAxes = Axes.Both
-                }
-            };
+
+            Children = new[] { new Box { RelativeSizeAxes = Axes.Both } };
         }
     }
 }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index 698939e278..481f0a6fc8 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -9,6 +9,7 @@ using osu.Game.Graphics.Backgrounds;
 using OpenTK.Graphics;
 using osu.Game.Beatmaps.ControlPoints;
 using osu.Framework.Audio.Track;
+using OpenTK;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 {
@@ -21,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
     /// </summary>
     public class CirclePiece : TaikoPiece
     {
-        public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER * 0.45f;
+        public const float SYMBOL_SIZE = 36;
         public const float SYMBOL_BORDER = 8;
         public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
         private const double pre_beat_transition_time = 80;
@@ -120,30 +121,20 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
                 },
                 content = new Container
                 {
-                    RelativeSizeAxes = Axes.Both,
                     Name = "Content",
                     Anchor = Anchor.Centre,
                     Origin = Anchor.Centre,
+                    RelativeSizeAxes = Axes.Both,
                 }
             });
 
             if (isStrong)
             {
-                Size *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
-
-                //default for symbols etc.
-                Content.Scale *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
+                content.Scale = new Vector2(TaikoHitObject.STRONG_SCALE);
+                content.Width = 1 / TaikoHitObject.STRONG_SCALE;
             }
         }
 
-        protected override void Update()
-        {
-            base.Update();
-
-            //we want to allow for width of content to remain mapped to the area inside us, regardless of the scale applied above.
-            Content.Width = 1 / Content.Scale.X;
-        }
-
         private const float edge_alpha_kiai = 0.5f;
 
         private void resetEdgeEffects()
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
index f607e2040f..ce591335f8 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
@@ -18,8 +18,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         /// </summary>
         public float Length;
 
-        public ElongatedCirclePiece(bool isStrong = false) : base(isStrong)
+        public ElongatedCirclePiece(bool isStrong = false)
+            : base(isStrong)
         {
+            RelativeSizeAxes = Axes.Y;
         }
 
         protected override void Update()
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
index 704a27a96d..9745b6b42d 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
@@ -18,7 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         {
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
+
             Size = new Vector2(CirclePiece.SYMBOL_SIZE);
+
             BorderThickness = CirclePiece.SYMBOL_BORDER;
             BorderColour = Color4.White;
             Masking = true;
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index 0f703837a9..8e5ab14bac 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -1,7 +1,10 @@
 // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
+using System;
+using OpenTK;
 using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
 using osu.Game.Graphics;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
@@ -15,9 +18,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         {
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
-            UseFullGlyphHeight = true;
+
             TextSize = CirclePiece.SYMBOL_INNER_SIZE;
+
             Icon = FontAwesome.fa_asterisk;
+            UseFullGlyphHeight = true;
             Shadow = false;
         }
     }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
index 5e7e9e6350..b942809172 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
@@ -5,6 +5,9 @@ using osu.Game.Graphics;
 using OpenTK;
 using OpenTK.Graphics;
 using osu.Game.Graphics.Containers;
+using osu.Framework.Graphics;
+using System;
+using osu.Framework.Graphics.Containers;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 {
@@ -35,8 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 
         public TaikoPiece()
         {
-            //just a default
-            Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
+            RelativeSizeAxes = Axes.Both;
         }
     }
 }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
index 2af65f2ed7..5f864bc554 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
@@ -15,12 +15,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         /// Any tick that is not the first for a drumroll is not filled, but is instead displayed
         /// as a hollow circle. This is what controls the border width of that circle.
         /// </summary>
-        private const float tick_border_width = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 16;
+        private const float tick_border_width = 5;
 
         /// <summary>
         /// The size of a tick.
         /// </summary>
-        private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 6;
+        private const float tick_size = 14;
 
         private bool filled;
         public bool Filled
@@ -37,6 +37,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 
         public TickPiece()
         {
+            Anchor = Anchor.Centre;
+            Origin = Anchor.Centre;
+
+            RelativeSizeAxes = Axes.None;
             Size = new Vector2(tick_size);
 
             Add(new CircularContainer

From e55a406e4dff3d7483e3fb48686de9a7a8a56bf7 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:54:13 +0930
Subject: [PATCH 11/19] Fix DrawableTaikoHitObject + drawable hit objects.

---
 .../Objects/Drawables/DrawableDrumRoll.cs     |   4 +
 .../Objects/Drawables/DrawableDrumRollTick.cs |   1 +
 .../Objects/Drawables/DrawableHit.cs          |   1 +
 .../Objects/Drawables/DrawableSwell.cs        | 116 ++++++++----------
 .../Drawables/DrawableTaikoHitObject.cs       |  18 +--
 5 files changed, 63 insertions(+), 77 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index 4562501ed1..756eff6fdf 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -10,6 +10,7 @@ using osu.Game.Rulesets.Taiko.Judgements;
 using OpenTK;
 using OpenTK.Graphics;
 using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
+using osu.Framework.Graphics;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 {
@@ -30,6 +31,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         public DrawableDrumRoll(DrumRoll drumRoll)
             : base(drumRoll)
         {
+            RelativeSizeAxes = Axes.Y;
+            AutoSizeAxes = Axes.X;
+
             foreach (var tick in drumRoll.Ticks)
             {
                 var newTick = new DrawableDrumRollTick(tick)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
index b64bc64d9b..0e1cd05de3 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
@@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         public DrawableDrumRollTick(DrumRollTick tick)
             : base(tick)
         {
+            FillMode = FillMode.Fit;
         }
 
         protected override TaikoPiece CreateMainPiece() => new TickPiece
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index 0d5c8d2a25..de2decbda9 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         protected DrawableHit(Hit hit)
             : base(hit)
         {
+            FillMode = FillMode.Fit;
         }
 
         protected override void CheckJudgement(bool userTriggered)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index a565f92fac..e861af03cf 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -35,8 +35,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         private readonly CircularContainer targetRing;
         private readonly CircularContainer expandingRing;
 
-        private readonly CirclePiece circlePiece;
-
         private readonly Key[] rimKeys = { Key.D, Key.K };
         private readonly Key[] centreKeys = { Key.F, Key.J };
         private Key[] lastKeySet;
@@ -52,89 +50,81 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         public DrawableSwell(Swell swell)
             : base(swell)
         {
-            Children = new Drawable[]
+            FillMode = FillMode.Fit;
+
+            Add(bodyContainer = new Container
             {
-                bodyContainer = new Container
+                RelativeSizeAxes = Axes.Both,
+                Depth = 1,
+                Children = new Drawable[]
                 {
-                    AutoSizeAxes = Axes.Both,
-                    Children = new Drawable[]
+                    expandingRing = new CircularContainer
                     {
-                        expandingRing = new CircularContainer
+                        Name = "Expanding ring",
+                        Anchor = Anchor.Centre,
+                        Origin = Anchor.Centre,
+                        Alpha = 0,
+                        RelativeSizeAxes = Axes.Both,
+                        BlendingMode = BlendingMode.Additive,
+                        Masking = true,
+                        Children = new[]
                         {
-                            Name = "Expanding ring",
-                            Anchor = Anchor.Centre,
-                            Origin = Anchor.Centre,
-                            Alpha = 0,
-                            Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
-                            BlendingMode = BlendingMode.Additive,
-                            Masking = true,
-                            Children = new[]
+                            new Box
                             {
-                                new Box
-                                {
-                                    RelativeSizeAxes = Axes.Both,
-                                    Alpha = inner_ring_alpha,
-                                }
+                                RelativeSizeAxes = Axes.Both,
+                                Alpha = inner_ring_alpha,
                             }
-                        },
-                        targetRing = new CircularContainer
+                        }
+                    },
+                    targetRing = new CircularContainer
+                    {
+                        Name = "Target ring (thick border)",
+                        Anchor = Anchor.Centre,
+                        Origin = Anchor.Centre,
+                        RelativeSizeAxes = Axes.Both,
+                        Masking = true,
+                        BorderThickness = target_ring_thick_border,
+                        BlendingMode = BlendingMode.Additive,
+                        Children = new Drawable[]
                         {
-                            Name = "Target ring (thick border)",
-                            Anchor = Anchor.Centre,
-                            Origin = Anchor.Centre,
-                            Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
-                            Masking = true,
-                            BorderThickness = target_ring_thick_border,
-                            BlendingMode = BlendingMode.Additive,
-                            Children = new Drawable[]
+                            new Box
                             {
-                                new Box
+                                RelativeSizeAxes = Axes.Both,
+                                Alpha = 0,
+                                AlwaysPresent = true
+                            },
+                            new CircularContainer
+                            {
+                                Name = "Target ring (thin border)",
+                                Anchor = Anchor.Centre,
+                                Origin = Anchor.Centre,
+                                RelativeSizeAxes = Axes.Both,
+                                Masking = true,
+                                BorderThickness = target_ring_thin_border,
+                                BorderColour = Color4.White,
+                                Children = new[]
                                 {
-                                    RelativeSizeAxes = Axes.Both,
-                                    Alpha = 0,
-                                    AlwaysPresent = true
-                                },
-                                new CircularContainer
-                                {
-                                    Name = "Target ring (thin border)",
-                                    Anchor = Anchor.Centre,
-                                    Origin = Anchor.Centre,
-                                    RelativeSizeAxes = Axes.Both,
-                                    Masking = true,
-                                    BorderThickness = target_ring_thin_border,
-                                    BorderColour = Color4.White,
-                                    Children = new[]
+                                    new Box
                                     {
-                                        new Box
-                                        {
-                                            RelativeSizeAxes = Axes.Both,
-                                            Alpha = 0,
-                                            AlwaysPresent = true
-                                        }
+                                        RelativeSizeAxes = Axes.Both,
+                                        Alpha = 0,
+                                        AlwaysPresent = true
                                     }
                                 }
                             }
-                        },
-                        circlePiece = new CirclePiece
-                        {
-                            Anchor = Anchor.Centre,
-                            Origin = Anchor.Centre,
-                            Children = new[]
-                            {
-                                symbol = new SwellSymbolPiece()
-                            }
                         }
                     }
                 }
-            };
+            });
+
+            MainPiece.Add(symbol = new SwellSymbolPiece());
 
-            circlePiece.KiaiMode = HitObject.Kiai;
         }
 
         [BackgroundDependencyLoader]
         private void load(OsuColour colours)
         {
-            circlePiece.AccentColour = colours.YellowDark;
+            MainPiece.AccentColour = colours.YellowDark;
             expandingRing.Colour = colours.YellowLight;
             targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
         }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index 24aa366944..84fe36e6d9 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -10,6 +10,7 @@ using osu.Game.Rulesets.Taiko.Judgements;
 using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
 using OpenTK;
 using OpenTK.Input;
+using System;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 {
@@ -24,12 +25,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
         public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
 
-        protected override Container<Drawable> Content => bodyContainer;
-
         protected readonly TaikoPiece MainPiece;
 
-        private readonly Container bodyContainer;
-
         public new TaikoHitType HitObject;
 
         protected DrawableTaikoHitObject(TaikoHitType hitObject)
@@ -40,19 +37,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
             Anchor = Anchor.CentreLeft;
             Origin = Anchor.Custom;
 
-            AutoSizeAxes = Axes.Both;
+            RelativeSizeAxes = Axes.Both;
+            Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
 
             RelativePositionAxes = Axes.X;
 
-            AddInternal(bodyContainer = new Container
-            {
-                AutoSizeAxes = Axes.Both,
-                Children = new[]
-                {
-                    MainPiece = CreateMainPiece()
-                }
-            });
-
+            Add(MainPiece = CreateMainPiece());
             MainPiece.KiaiMode = HitObject.Kiai;
 
             LifetimeStart = HitObject.StartTime - HitObject.ScrollTime * 2;

From 8ef949ce38f8e7187525a5bbcc33cec96e073c37 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 13:56:36 +0930
Subject: [PATCH 12/19] Remove TestCaseTaikoHitObjects.

---
 .../Tests/TestCaseTaikoHitObjects.cs          | 119 ------------------
 .../osu.Desktop.VisualTests.csproj            |   1 -
 2 files changed, 120 deletions(-)
 delete mode 100644 osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
deleted file mode 100644
index d98e39ae7b..0000000000
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using System.Linq;
-using OpenTK;
-using OpenTK.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Testing;
-using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
-
-namespace osu.Desktop.VisualTests.Tests
-{
-    internal class TestCaseTaikoHitObjects : TestCase
-    {
-        public override string Description => "Taiko hit objects";
-
-        private bool kiai;
-
-        public TestCaseTaikoHitObjects()
-        {
-            AddToggleStep("Kiai", b =>
-            {
-                kiai = !kiai;
-                updateKiaiState();
-            });
-
-            Add(new CirclePiece
-            {
-                Position = new Vector2(100, 100),
-                AccentColour = Color4.DarkRed,
-                KiaiMode = kiai,
-                Children = new[]
-                {
-                    new CentreHitSymbolPiece()
-                }
-            });
-
-            Add(new CirclePiece(true)
-            {
-                Position = new Vector2(350, 100),
-                AccentColour = Color4.DarkRed,
-                KiaiMode = kiai,
-                Children = new[]
-                {
-                    new CentreHitSymbolPiece()
-                }
-            });
-
-            Add(new CirclePiece
-            {
-                Position = new Vector2(100, 300),
-                AccentColour = Color4.DarkBlue,
-                KiaiMode = kiai,
-                Children = new[]
-                {
-                    new RimHitSymbolPiece()
-                }
-            });
-
-            Add(new CirclePiece(true)
-            {
-                Position = new Vector2(350, 300),
-                AccentColour = Color4.DarkBlue,
-                KiaiMode = kiai,
-                Children = new[]
-                {
-                    new RimHitSymbolPiece()
-                }
-            });
-
-            Add(new CirclePiece
-            {
-                Position = new Vector2(100, 500),
-                AccentColour = Color4.Orange,
-                KiaiMode = kiai,
-                Children = new[]
-                {
-                    new SwellSymbolPiece()
-                }
-            });
-
-            Add(new ElongatedCirclePiece
-            {
-                Position = new Vector2(575, 100),
-                AccentColour = Color4.Orange,
-                KiaiMode = kiai,
-                Length = 0.10f,
-                PlayfieldLengthReference = () => DrawSize.X
-            });
-
-            Add(new ElongatedCirclePiece(true)
-            {
-                Position = new Vector2(575, 300),
-                AccentColour = Color4.Orange,
-                KiaiMode = kiai,
-                Length = 0.10f,
-                PlayfieldLengthReference = () => DrawSize.X
-            });
-        }
-
-        private void updateKiaiState()
-        {
-            foreach (var c in Children.OfType<CirclePiece>())
-                c.KiaiMode = kiai;
-        }
-
-        private abstract class BaseCircle : Container
-        {
-            protected readonly CirclePiece Piece;
-
-            protected BaseCircle(CirclePiece piece)
-            {
-                Piece = piece;
-
-                Add(Piece);
-            }
-        }
-    }
-}
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index 1f4fd80ca6..515fa4347d 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -211,7 +211,6 @@
     <Compile Include="Tests\TestCaseScrollingHitObjects.cs" />
     <Compile Include="Tests\TestCaseSkipButton.cs" />
     <Compile Include="Tests\TestCaseTabControl.cs" />
-    <Compile Include="Tests\TestCaseTaikoHitObjects.cs" />
     <Compile Include="Tests\TestCaseTaikoPlayfield.cs" />
     <Compile Include="Tests\TestCaseTextAwesome.cs" />
     <Compile Include="Tests\TestCasePlaySongSelect.cs" />

From c2475f67215c5b93accd2f139dc78e5b21ac2725 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 14:18:54 +0930
Subject: [PATCH 13/19] Fix gravity.

---
 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index de2decbda9..5a17355cdb 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -93,12 +93,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
                         Content.ScaleTo(0.8f, gravity_time * 2, Easing.OutQuad);
 
-                        this.FadeOut(800)
-                            .MoveToY(-gravity_travel_height, gravity_time, Easing.Out)
+                        this.MoveToY(-gravity_travel_height, gravity_time, Easing.Out)
                             .Then()
                             .MoveToY(gravity_travel_height * 2, gravity_time * 2, Easing.In);
 
-                        Expire();
+                        this.FadeOut(800)
+                            .Expire();
+
                         break;
                 }
             }

From dc0d0a3602a4000cc3bf1c6f2e88366469cb9d13 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 14:31:20 +0930
Subject: [PATCH 14/19] CI.

---
 .../Objects/Drawables/DrawableTaikoHitObject.cs            | 2 --
 .../Objects/Drawables/Pieces/SwellSymbolPiece.cs           | 3 ---
 .../Objects/Drawables/Pieces/TaikoPiece.cs                 | 3 ---
 osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs          | 7 +++----
 osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs               | 1 -
 5 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index 84fe36e6d9..f039f35533 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -3,14 +3,12 @@
 
 using System.Collections.Generic;
 using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
 using osu.Framework.Input;
 using osu.Game.Rulesets.Objects.Drawables;
 using osu.Game.Rulesets.Taiko.Judgements;
 using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
 using OpenTK;
 using OpenTK.Input;
-using System;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 {
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index 8e5ab14bac..d4f57f5959 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -1,10 +1,7 @@
 // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
-using System;
-using OpenTK;
 using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
 using osu.Game.Graphics;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
index b942809172..4b40bbf384 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
@@ -2,12 +2,9 @@
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
 using osu.Game.Graphics;
-using OpenTK;
 using OpenTK.Graphics;
 using osu.Game.Graphics.Containers;
 using osu.Framework.Graphics;
-using System;
-using osu.Framework.Graphics.Containers;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 {
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index 5f3223e918..7e7dc3662f 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -4,24 +4,23 @@
 using osu.Game.Beatmaps;
 using osu.Game.Beatmaps.ControlPoints;
 using osu.Game.Rulesets.Objects;
-using osu.Game.Rulesets.Taiko.UI;
 
 namespace osu.Game.Rulesets.Taiko.Objects
 {
     public abstract class TaikoHitObject : HitObject
     {
         /// <summary>
-        /// Default size of a <see cref="DrawableTaikoHitObject"/>.
+        /// Default size of a drawable taiko hit object.
         /// </summary>
         public const float DEFAULT_SIZE = 0.45f;
 
         /// <summary>
-        /// Scale multiplier for a strong <see cref="DrawableTaikoHitObject"/>.
+        /// Scale multiplier for a strong drawable taiko hit object.
         /// </summary>
         public const float STRONG_SCALE = 1.4f;
 
         /// <summary>
-        /// Default size of a strong <see cref="DrawableTaikoHitObject"/>.
+        /// Default size of a strong drawable taiko hit object.
         /// </summary>
         public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
 
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index fff19b97c9..dca339f734 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -15,7 +15,6 @@ using osu.Framework.Graphics.Containers;
 using osu.Framework.Extensions.Color4Extensions;
 using System.Linq;
 using osu.Game.Rulesets.Taiko.Objects.Drawables;
-using System;
 
 namespace osu.Game.Rulesets.Taiko.UI
 {

From 8553e1cad30aec950729d360debedaf12e14918f Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 14:38:24 +0930
Subject: [PATCH 15/19] Same default value for parameter.

---
 osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 3f4d4e9722..23797f8e21 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -88,7 +88,7 @@ namespace osu.Desktop.VisualTests.Tests
                     addDrumRoll(true);
                     break;
                 case 5:
-                    addSwell(1000);
+                    addSwell();
                     delay = scroll_time - 100;
                     break;
             }

From 09c0e18a04a63876aab159f4f7a8664c6449770f Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 15:47:23 +0930
Subject: [PATCH 16/19] Fix incorrect size reset function.

---
 osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 23797f8e21..717538ff89 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -100,7 +100,7 @@ namespace osu.Desktop.VisualTests.Tests
                     playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
                     break;
                 case 6:
-                    playfieldContainer.Delay(delay).ResizeTo(new Vector2(TaikoPlayfield.DEFAULT_HEIGHT), 500);
+                    playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_HEIGHT), 500);
                     break;
             }
         }

From 74e9449a7574e38f9df7d41cc12c62806f1f0aaf Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 15:57:45 +0930
Subject: [PATCH 17/19] Make symbol pieces relative sized.

---
 .../Drawables/Pieces/CentreHitSymbolPiece.cs  | 17 ++++++++---
 .../Objects/Drawables/Pieces/CirclePiece.cs   |  3 +-
 .../Drawables/Pieces/SwellSymbolPiece.cs      | 29 +++++++++++++++----
 3 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
index 8ad548b3d6..f4c78251d0 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
@@ -11,17 +11,26 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
     /// <summary>
     /// The symbol used for centre hit pieces.
     /// </summary>
-    public class CentreHitSymbolPiece : CircularContainer
+    public class CentreHitSymbolPiece : Container
     {
         public CentreHitSymbolPiece()
         {
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
 
-            Size = new Vector2(CirclePiece.SYMBOL_INNER_SIZE);
-            Masking = true;
+            RelativeSizeAxes = Axes.Both;
+            Size = new Vector2(CirclePiece.SYMBOL_SIZE);
+            Padding = new MarginPadding(CirclePiece.SYMBOL_BORDER);
 
-            Children = new[] { new Box { RelativeSizeAxes = Axes.Both } };
+            Children = new[]
+            {
+                new CircularContainer
+                {
+                    RelativeSizeAxes = Axes.Both,
+                    Masking = true,
+                    Children = new[] { new Box { RelativeSizeAxes = Axes.Both } }
+                }
+            };
         }
     }
 }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index 481f0a6fc8..541c774cca 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -22,9 +22,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
     /// </summary>
     public class CirclePiece : TaikoPiece
     {
-        public const float SYMBOL_SIZE = 36;
+        public const float SYMBOL_SIZE = 0.35f;
         public const float SYMBOL_BORDER = 8;
-        public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
         private const double pre_beat_transition_time = 80;
 
         /// <summary>
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index d4f57f5959..cf16d53bb4 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -1,7 +1,10 @@
 // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
+using System;
+using OpenTK;
 using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
 using osu.Game.Graphics;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
@@ -9,18 +12,34 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
     /// <summary>
     /// The symbol used for swell pieces.
     /// </summary>
-    public class SwellSymbolPiece : TextAwesome
+    public class SwellSymbolPiece : Container
     {
+        private readonly TextAwesome symbol;
+
         public SwellSymbolPiece()
         {
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
 
-            TextSize = CirclePiece.SYMBOL_INNER_SIZE;
+            RelativeSizeAxes = Axes.Both;
+            Size = new Vector2(CirclePiece.SYMBOL_SIZE);
+            Padding = new MarginPadding(CirclePiece.SYMBOL_BORDER);
 
-            Icon = FontAwesome.fa_asterisk;
-            UseFullGlyphHeight = true;
-            Shadow = false;
+            Children = new[]
+            {
+                symbol = new TextAwesome
+                {
+                    Icon = FontAwesome.fa_asterisk,
+                    UseFullGlyphHeight = true,
+                    Shadow = false
+                }
+            };
+        }
+
+        protected override void Update()
+        {
+            base.Update();
+            symbol.TextSize = Math.Min(ChildSize.X, ChildSize.Y);
         }
     }
 }

From 351d255355f3b967eaa4e11f94b0c8e76b982201 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 20:04:35 +0930
Subject: [PATCH 18/19] Fix brokenness due to relative sizes.

---
 .../Objects/Drawables/Pieces/CirclePiece.cs               | 8 +-------
 .../Objects/Drawables/Pieces/RimHitSymbolPiece.cs         | 1 +
 .../Objects/Drawables/Pieces/SwellSymbolPiece.cs          | 1 -
 .../Objects/Drawables/Pieces/TickPiece.cs                 | 5 +++--
 4 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index 541c774cca..c4746a664b 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
     /// </summary>
     public class CirclePiece : TaikoPiece
     {
-        public const float SYMBOL_SIZE = 0.35f;
+        public const float SYMBOL_SIZE = 0.45f;
         public const float SYMBOL_BORDER = 8;
         private const double pre_beat_transition_time = 80;
 
@@ -126,12 +126,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
                     RelativeSizeAxes = Axes.Both,
                 }
             });
-
-            if (isStrong)
-            {
-                content.Scale = new Vector2(TaikoHitObject.STRONG_SCALE);
-                content.Width = 1 / TaikoHitObject.STRONG_SCALE;
-            }
         }
 
         private const float edge_alpha_kiai = 0.5f;
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
index 9745b6b42d..60224a291d 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
@@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
 
+            RelativeSizeAxes = Axes.Both;
             Size = new Vector2(CirclePiece.SYMBOL_SIZE);
 
             BorderThickness = CirclePiece.SYMBOL_BORDER;
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index c1ab759e2b..ac10743539 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -6,7 +6,6 @@ using OpenTK;
 using osu.Framework.Graphics;
 using osu.Framework.Graphics.Containers;
 using osu.Game.Graphics;
-using OpenTK;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 {
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
index 5f864bc554..211bf910a4 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         /// <summary>
         /// The size of a tick.
         /// </summary>
-        private const float tick_size = 14;
+        private const float tick_size = 0.35f;
 
         private bool filled;
         public bool Filled
@@ -40,7 +40,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
             Anchor = Anchor.Centre;
             Origin = Anchor.Centre;
 
-            RelativeSizeAxes = Axes.None;
+            RelativeSizeAxes = Axes.Both;
+            FillMode = FillMode.Fit;
             Size = new Vector2(tick_size);
 
             Add(new CircularContainer

From ba31bfcdf12a76a085aaf015d62c8c9565a2a367 Mon Sep 17 00:00:00 2001
From: smoogipooo <smoogipooo@gmail.com>
Date: Thu, 3 Aug 2017 20:19:50 +0930
Subject: [PATCH 19/19] CI fixes.

---
 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs  | 2 +-
 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs | 3 ---
 .../Objects/Drawables/DrawableTaikoHitObject.cs                | 2 +-
 .../Objects/Drawables/Pieces/CirclePiece.cs                    | 3 +--
 .../Objects/Drawables/Pieces/ElongatedCirclePiece.cs           | 3 +--
 .../Objects/Drawables/Pieces/SwellSymbolPiece.cs               | 1 -
 6 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index 756eff6fdf..74f0f2326d 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
         protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
 
-        protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece(HitObject.IsStrong)
+        protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece
         {
             Length = (float)(HitObject.Duration / HitObject.ScrollTime),
             PlayfieldLengthReference = () => Parent.DrawSize.X
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
index 1c6b12ea43..57e7eea470 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
@@ -7,7 +7,6 @@ using osu.Framework.Input;
 using osu.Game.Rulesets.Objects.Drawables;
 using osu.Game.Rulesets.Taiko.Judgements;
 using OpenTK.Input;
-using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 {
@@ -28,8 +27,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
         {
         }
 
-        protected override TaikoPiece CreateMainPiece() => new CirclePiece(true);
-
         protected override TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement();
 
         protected override void CheckJudgement(bool userTriggered)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index f039f35533..510994ed70 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
         protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
 
-        protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(HitObject.IsStrong);
+        protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
 
         /// <summary>
         /// Sets the scroll position of the DrawableHitObject relative to the offset between
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index c4746a664b..ba717371dd 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -9,7 +9,6 @@ using osu.Game.Graphics.Backgrounds;
 using OpenTK.Graphics;
 using osu.Game.Beatmaps.ControlPoints;
 using osu.Framework.Audio.Track;
-using OpenTK;
 
 namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 {
@@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
 
         public Box FlashBox;
 
-        public CirclePiece(bool isStrong = false)
+        public CirclePiece()
         {
             EarlyActivationMilliseconds = pre_beat_transition_time;
 
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
index ce591335f8..2f5b4eefd6 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
@@ -18,8 +18,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
         /// </summary>
         public float Length;
 
-        public ElongatedCirclePiece(bool isStrong = false)
-            : base(isStrong)
+        public ElongatedCirclePiece()
         {
             RelativeSizeAxes = Axes.Y;
         }
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index ac10743539..c3fdc671a4 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -1,7 +1,6 @@
 // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
 // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
 
-using System;
 using OpenTK;
 using osu.Framework.Graphics;
 using osu.Framework.Graphics.Containers;