diff --git a/README.md b/README.md
index 621d055..effde5a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
# Tick Manager
Constant application tick rate library
+
+ Usage
+
diff --git a/TickManager.csproj b/TickManager.csproj
new file mode 100644
index 0000000..5fe1fc7
--- /dev/null
+++ b/TickManager.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netcoreapp3.1
+ Library
+
+
+
diff --git a/src/TickClock.cs b/src/TickClock.cs
new file mode 100644
index 0000000..5dcb223
--- /dev/null
+++ b/src/TickClock.cs
@@ -0,0 +1,42 @@
+using Microsoft.Win32;
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Security;
+
+namespace TickManager
+{
+ ///
+ /// Clock that calculates tick time
+ ///
+ public class TickClock
+ {
+ ///
+ /// The ammount of ticks a millisecond has
+ ///
+ internal const double TicksPerMillisecond = 10000;
+
+ ///
+ /// Internal application start timestamp
+ ///
+ internal double startTimeStamp;
+
+ ///
+ /// Resets the TickClock
+ ///
+ public void Reset()
+ {
+ startTimeStamp = TickHelper.GetCurrentTimestamp();
+ }
+
+ ///
+ /// Register an application tick
+ ///
+ /// The amount of time the application took to register a tick
+ public double Tick()
+ {
+ long currentTimestamp = TickHelper.GetCurrentTimestamp();
+ return (currentTimestamp - startTimeStamp) / TicksPerMillisecond;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/TickHelper.cs b/src/TickHelper.cs
new file mode 100644
index 0000000..b1d4439
--- /dev/null
+++ b/src/TickHelper.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Text;
+
+namespace TickManager
+{
+ internal static class NativeMethods
+ {
+ [DllImport("kernel32.dll")]
+ [ResourceExposure(ResourceScope.None)]
+ public static extern bool QueryPerformanceCounter(out long value);
+ }
+
+ ///
+ /// Helper functions
+ ///
+ public static class TickHelper
+ {
+ ///
+ /// Convert ticks per second to milliseconds per tick
+ ///
+ /// Ticks per second
+ /// Milliseconds per tick
+ public static double TpsToMspt(double tps)
+ {
+ return 1D / tps * 1000;
+ }
+
+ ///
+ /// Converts milliseconds per tick to ticks per second
+ ///
+ /// Milliseconds per tick
+ /// Ticks per second
+ public static double MsptToTps(double mspt)
+ {
+ return 1D / mspt * 1000;
+ }
+
+ internal static long GetCurrentTimestamp()
+ {
+ long timestamp;
+
+ // took it from Stopwatch
+ // maybe find a better way to get the current timestamp
+ NativeMethods.QueryPerformanceCounter(out timestamp);
+ return timestamp;
+ }
+ }
+}
diff --git a/src/TickManager.cs b/src/TickManager.cs
new file mode 100644
index 0000000..6f330a0
--- /dev/null
+++ b/src/TickManager.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TickManager
+{
+ ///
+ /// Handles ticking for an application
+ ///
+ public class TickManager
+ {
+ ///
+ /// The frequency the application should be running at
+ ///
+ internal double internalFrequency;
+
+ ///
+ /// Variable to store the milliseconds each tick should take
+ ///
+ internal double msptInternal;
+
+ ///
+ /// Tick clock object
+ ///
+ internal TickClock tc = new TickClock();
+
+ ///
+ /// The frequency your application will tick
+ ///
+ public int Frequency
+ {
+ get => (int)internalFrequency;
+ set
+ {
+ // Tries to get an exact aproximation to the integer because Math...
+ internalFrequency = value + 0.001;
+ msptInternal = TickHelper.TpsToMspt(internalFrequency);
+ }
+ }
+
+ ///
+ /// Milliseconds per tick that took to run last tick
+ ///
+ public double MSPT { get; private set; }
+
+ ///
+ /// The ticks per second the server is running at relative to last tick
+ ///
+ public double TPS
+ {
+ get => TickHelper.MsptToTps(MSPT);
+ }
+
+ ///
+ /// Checks if the application can process the same tick relative to the frequency set
+ ///
+ /// Whether the application should process the next tick or not
+ public bool CanTick()
+ {
+ double internalMspt = tc.Tick();
+ bool canTick = internalMspt > msptInternal;
+ if (canTick)
+ {
+ MSPT = internalMspt;
+ tc.Reset();
+ }
+ return canTick;
+ }
+ }
+}