diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Cerek Hillen
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/spice.cabal b/spice.cabal
new file mode 100644
--- /dev/null
+++ b/spice.cabal
@@ -0,0 +1,35 @@
+name:                spice
+version:             0.1.0.0
+synopsis:            An FRP-based game engine written in Haskell.
+description:         An FRP-based game engine written in Haskell. - See the homepage for more information.
+homepage:            http://github.com/crockeo/spice
+license:             MIT
+license-file:        LICENSE
+author:              Cerek Hillen
+maintainer:          Cerek Hillen <cerekh@gmail.com>
+copyright:           (c) 2014, Cerek Hillen
+category:            FRP
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     FRP.Spice
+                       FRP.Spice.Config
+                       FRP.Spice.Engine
+                       FRP.Spice.Game
+                       FRP.Spice.Input
+                       FRP.Spice.Input.Keyboard
+                       FRP.Spice.Input.Mouse
+                       FRP.Spice.Input.MousePosition
+                       FRP.Spice.Math.Vector
+
+  hs-source-dirs:      src/
+
+  build-depends:       base         == 4.7.*
+               ,       elerea       == 2.7.*
+               ,       GLFW         == 0.5.*
+               ,       containers   == 0.5.*
+               ,       data-default == 0.5.*
+               ,       OpenGL
+
+  default-language:    Haskell2010
diff --git a/src/FRP/Spice.hs b/src/FRP/Spice.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice.hs
@@ -0,0 +1,8 @@
+module FRP.Spice (module Rexport) where
+
+-----------------------
+-- Rexported Imports --
+import FRP.Spice.Config as Rexport
+import FRP.Spice.Engine as Rexport
+import FRP.Spice.Input  as Rexport
+import FRP.Spice.Game   as Rexport
diff --git a/src/FRP/Spice/Config.hs b/src/FRP/Spice/Config.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Config.hs
@@ -0,0 +1,31 @@
+module FRP.Spice.Config where
+
+--------------------
+-- Global Imports --
+import Data.Default
+
+----------
+-- Code --
+
+-- The window config
+data WindowConfig = WindowConfig { getWindowWidth      :: Int
+                                 , getWindowHeight     :: Int
+                                 , getWindowFullscreen :: Bool
+                                 , getWindowResizable  :: Bool
+                                 , getWindowTitle      :: String
+                                 }
+  deriving (Eq, Show, Read)
+
+-- The default window config
+defaultWindowConfig :: WindowConfig
+defaultWindowConfig = WindowConfig { getWindowWidth      = 640
+                                   , getWindowHeight     = 480
+                                   , getWindowFullscreen = False
+                                   , getWindowResizable  = False
+                                   , getWindowTitle      = "Spice Application"
+                                   }
+
+-- A default instance for the window
+-- config
+instance Default WindowConfig where
+  def = defaultWindowConfig
diff --git a/src/FRP/Spice/Engine.hs b/src/FRP/Spice/Engine.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Engine.hs
@@ -0,0 +1,54 @@
+module FRP.Spice.Engine where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Data.IORef
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Engine.RunInput
+import FRP.Spice.Engine.Network
+import FRP.Spice.Engine.Driver
+import FRP.Spice.Config
+import FRP.Spice.Input
+import FRP.Spice.Game
+
+----------
+-- Code --
+
+-- Starting the engine
+startEngine :: Game a => WindowConfig -> a -> IO ()
+startEngine wc game = do
+  -- Opening the window
+  initialize
+  openWindow (Size 640 480) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window
+
+  -- Checking for the window being closed
+  closed <- newIORef False
+  windowCloseCallback $= do
+    writeIORef closed True
+    return True
+
+  -- Getting an external of the game
+  (gameSignal, gameSink) <- external game
+
+  -- Getting the input container
+  ic <- makeInputContainer
+
+  -- Updating the input
+  mousePosCallback    $= makeMousePositionCallback ic
+  keyCallback         $= makeKeyboardCallback ic
+  mouseButtonCallback $= makeMouseCallback ic
+
+  -- Creating the network
+  network <- makeNetwork (getInput ic) gameSignal gameSink
+
+  -- Driving the network
+  GLFW.time $= 0
+  driveNetwork network $ runInput closed
+
+  -- Closing the window, after all is said and done
+  closeWindow
diff --git a/src/FRP/Spice/Game.hs b/src/FRP/Spice/Game.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Game.hs
@@ -0,0 +1,13 @@
+module FRP.Spice.Game where
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Input
+
+----------
+-- Code --
+
+-- The game instance, to be used with updating and rendering
+class Game a where
+  update :: Float -> Input -> a -> a
+  render :: a -> IO ()
diff --git a/src/FRP/Spice/Input.hs b/src/FRP/Spice/Input.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Input.hs
@@ -0,0 +1,90 @@
+module FRP.Spice.Input ( module Rexport
+                       , Sinks (..)
+                       , Input (..)
+                       , InputContainer (..)
+                       , makeInputContainer
+                       , makeMousePositionCallback
+                       , makeKeyboardCallback
+                       , makeMouseCallback
+                       ) where
+
+--------------------
+-- Global Imports --
+import Data.Map.Strict hiding (keys, map)
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import Control.Applicative
+import FRP.Elerea.Param
+
+-------------------
+-- Local Imports --
+import qualified FRP.Spice.Input.MousePosition as MousePosition
+import qualified FRP.Spice.Input.Keyboard as Keyboard
+import qualified FRP.Spice.Input.Mouse as Mouse
+import FRP.Spice.Math.Vector
+
+-----------------------
+-- Rexported Imports --
+import Data.Map.Strict  as Rexport ((!))
+import Graphics.UI.GLFW as Rexport (Key (..), SpecialKey (..), MouseButton (..))
+
+----------
+-- Code --
+
+-- The sinks
+data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()
+                   , keyboardSinks      :: Map Key (Bool -> IO ())
+                   , mouseSinks         :: Map MouseButton (Bool -> IO ())
+                   }
+
+data Input = Input { mousePosition :: Vector Float
+                   , keyboard      :: Map Key Bool
+                   , mouse         :: Map MouseButton Bool
+                   }
+
+-- The container to go around the
+data InputContainer = InputContainer { getSinks :: Sinks
+                                     , getInput :: Signal Input
+                                     }
+
+-- Creating the input container for use in the program
+makeInputContainer :: IO InputContainer
+makeInputContainer = do
+  mousePositionExternals <- MousePosition.externals
+  keyboardExternals      <- Keyboard.externals
+  mouseExternals         <- Mouse.externals
+
+  let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals
+                    , keyboardSinks      = Keyboard.sinks keyboardExternals
+                    , mouseSinks         = Mouse.sinks mouseExternals
+                    }
+
+  let input = do mps <- fst mousePositionExternals
+                 kbs <- Keyboard.signals keyboardExternals
+                 ms  <- Mouse.signals mouseExternals
+
+                 return Input { mousePosition = mps
+                              , keyboard      = kbs
+                              , mouse         = ms
+                              }
+
+  return InputContainer { getSinks = sinks
+                        , getInput = input
+                        }
+
+-- Creating callbacks for each type
+makeMousePositionCallback :: InputContainer -> MousePosCallback
+makeMousePositionCallback ic (Position x y) =
+  mousePositionSinks (getSinks ic) $ Vector (fromIntegral x / 320 - 1) ((-fromIntegral y) / 240 - 1)
+
+makeKeyboardCallback :: InputContainer -> KeyCallback
+makeKeyboardCallback ic key state =
+  keyboardSinks (getSinks ic) ! key $ case state of
+    Press   -> True
+    Release -> False
+
+makeMouseCallback :: InputContainer -> MouseButtonCallback
+makeMouseCallback ic button state =
+  mouseSinks (getSinks ic) ! button $ case state of
+    Press   -> True
+    Release -> False
diff --git a/src/FRP/Spice/Input/Keyboard.hs b/src/FRP/Spice/Input/Keyboard.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Input/Keyboard.hs
@@ -0,0 +1,28 @@
+module FRP.Spice.Input.Keyboard where
+
+--------------------
+-- Global Imports --
+import qualified Data.Traversable as T
+import Data.Map.Strict hiding (keys, map)
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Control.Monad
+
+----------
+-- Code --
+
+-- A set of all keys available via GLFW
+keys :: [Key]
+keys = map toEnum [0 .. 318]
+
+-- Getting the externals for all of the keys
+externals :: IO (Map Key (Signal Bool, Bool -> IO ()))
+externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys
+
+-- Getting the signals from the externals
+signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool)
+signals = T.sequence . fmap fst
+
+-- Getting the sinks from the externals
+sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ())
+sinks = fmap snd
diff --git a/src/FRP/Spice/Input/Mouse.hs b/src/FRP/Spice/Input/Mouse.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Input/Mouse.hs
@@ -0,0 +1,43 @@
+module FRP.Spice.Input.Mouse where
+
+--------------------
+-- Global Imports --
+import qualified Data.Traversable as T (sequence)
+import Data.Map.Strict hiding (keys, map)
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Control.Monad
+import Data.Default
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Math.Vector
+
+----------
+-- Code --
+
+-- Adding an instance of Ord to MouseButton so it can be used with the map
+instance Ord MouseButton where
+  mb1 <= mb2 = fromEnum mb1 < fromEnum mb2
+
+-- A set of all mouse buttons available via GLFW
+buttons :: [MouseButton]
+buttons = [ ButtonLeft
+          , ButtonRight
+          , ButtonMiddle
+          ]
+          ++
+          map ButtonNo [0 .. 7]
+
+-- Getting externals for all of the buttons
+externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ()))
+externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons
+
+-- Getting the signals from the externals
+signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool)
+signals = T.sequence . fmap fst
+
+-- Getting the sinks from the externals
+sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ())
+sinks = fmap snd
diff --git a/src/FRP/Spice/Input/MousePosition.hs b/src/FRP/Spice/Input/MousePosition.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Input/MousePosition.hs
@@ -0,0 +1,24 @@
+module FRP.Spice.Input.MousePosition where
+
+--------------------
+-- Global Imports --
+import Graphics.Rendering.OpenGL
+import Graphics.UI.GLFW as GLFW
+import FRP.Elerea.Param
+import Data.Default
+
+-------------------
+-- Local Imports --
+import FRP.Spice.Math.Vector
+
+-- Getting the external for the mouse position
+externals :: IO (Signal (Vector Float), Vector Float -> IO ())
+externals = external def
+
+-- Getting the signal from the external
+signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float)
+signals = fst
+
+-- Getting the signal from the external
+sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO ()
+sinks = snd
diff --git a/src/FRP/Spice/Math/Vector.hs b/src/FRP/Spice/Math/Vector.hs
new file mode 100644
--- /dev/null
+++ b/src/FRP/Spice/Math/Vector.hs
@@ -0,0 +1,35 @@
+module FRP.Spice.Math.Vector where
+
+--------------------
+-- Global Imports --
+import Data.Default
+import Data.Monoid
+
+----------
+-- Code --
+
+-- The vector datatype
+data Vector a = Vector a a
+
+-- Default instance
+instance Default a => Default (Vector a) where
+  def = Vector def def
+
+-- Show instance
+instance Show a => Show (Vector a) where
+  show (Vector x y) = mconcat ["Vector ", show x, " ", show y]
+
+-- Num instance
+instance Num a => Num (Vector a) where
+  (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)
+  (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2)
+
+  fromInteger n = Vector (fromInteger n) (fromInteger n)
+
+  abs    (Vector x y) = Vector (abs    x) (abs    y)
+  signum (Vector x y) = Vector (signum x) (signum y)
+  negate (Vector x y) = Vector (negate x) (negate y)
+
+-- Functor instance
+instance Functor Vector where
+  fmap fn (Vector x y) = Vector (fn x) (fn y)
