diff --git a/lib/tiny.lua b/lib/tiny.lua
index 4fb3c89..290f938 100644
--- a/lib/tiny.lua
+++ b/lib/tiny.lua
@@ -905,6 +905,53 @@ function tiny.setSystemIndex(world, system, index)
     return oldIndex
 end
 
+---@author Sage Vaillancourt
+---
+--- A convenience function for quickly building a well-typed system matching the given shape.
+--- Typing does not work when a literal tiny filter is passed as the `shape`, but this function can still be convenient.
+---@generic T
+---@param name string The `.name` of the system. Shouldn't be used for identifying it in code, but can be helpful when debugging.
+---@param shape T | fun()
+---@param process fun(entity: T, dt: number, system: System) | nil
+---@param compare nil | fun(system: System, entityA: T, entityB: T): boolean If provided, will instead initialize a sortedProcessingSystem.
+---@return System | { entities: T[] }
+function tiny.filteredSystem(world, name, shape, process, compare)
+    assert(type(name) == "string")
+    assert(process == nil or type(process) == "function")
+
+    local system = compare and tiny.sortedProcessingSystem() or tiny.processingSystem()
+    system.compare = compare
+    system.name = name
+
+    if type(shape) == "table" then
+        local keys = {}
+        for key, value in pairs(shape) do
+            local isTable = type(value) == "table"
+            local isMaybe = isTable and value.maybe ~= nil
+
+            if not isMaybe then
+                -- ^ Don't require any Maybe types
+                keys[#keys + 1] = key
+            end
+        end
+        system.filter = tiny.requireAll(unpack(keys))
+    elseif type(shape) == "function" then
+        system.filter = shape
+    else
+        error("Unknown type for `shape` argument: " .. type(shape))
+    end
+
+    if not process then
+        return world:addSystem(system)
+    end
+
+    function system:process(e, dt)
+        process(e, dt, self)
+    end
+
+    return world:addSystem(system)
+end
+
 -- Construct world metatable.
 worldMetaTable = {
     __index = {
@@ -921,6 +968,7 @@ worldMetaTable = {
         getEntityCount = tiny.getEntityCount,
         getSystemCount = tiny.getSystemCount,
         setSystemIndex = tiny.setSystemIndex,
+        filteredSystem = tiny.filteredSystem,
     },
     __tostring = function()
         return "<tiny-ecs_World>"
diff --git a/main.lua b/main.lua
index 3b469f4..d7ed858 100644
--- a/main.lua
+++ b/main.lua
@@ -1,20 +1,17 @@
 require("tiny-debug")
 require("utils")
-require("tiny-tools")
-
-local tiny = require("lib/tiny")
-World = tiny.world()
-
 require("generated/filter-types")
 require("generated/assets")
 require("generated/all-systems")
 
+local world = require("world")
+
 local scenarios = {
     default = function()
         -- TODO: Add default entities
     end,
     textTestScenario = function()
-        World:addEntity({
+        world:addEntity({
             position = { x = 0, y = 600 },
             drawAsText = {
                 text = "Hello, world!",
@@ -41,7 +38,7 @@ function love.update(dt)
     delta = dt
 
     if love.keyboard.isDown("r") then
-        World:clearEntities()
+        world:clearEntities()
         currentScenario()
         freeze = false
     end
@@ -54,7 +51,7 @@ function love.update(dt)
         return
     end
 
-    World:update(delta, function(_, system)
+    world:update(delta, function(_, system)
         if system.deferToEnd then
             return false
         end
@@ -63,14 +60,14 @@ function love.update(dt)
 end
 
 function love.draw()
-    World:update(delta, function(_, system)
+    world:update(delta, function(_, system)
         if system.deferToEnd then
             return false
         end
         return system.isDrawSystem
     end)
 
-    World:update(delta, function(_, system)
+    world:update(delta, function(_, system)
         return system.deferToEnd
     end)
 end
diff --git a/systems/camera-pan.lua b/systems/camera-pan.lua
index 8f38509..99cd43b 100644
--- a/systems/camera-pan.lua
+++ b/systems/camera-pan.lua
@@ -1,15 +1,18 @@
-Camera = {
+local world = require("world")
+
+local camera = {
     pan = {
         x = 0,
         y = 0,
     },
 }
 
-expireBelowScreenSystem = filteredSystem("expireBelowScreen", { position = T.XyPair, expireBelowScreenBy = T.number })
+local expireBelowScreen =
+    world:filteredSystem("expireBelowScreen", { position = T.XyPair, expireBelowScreenBy = T.number })
 
 local focusPriority = {}
 
-cameraPanSystem = filteredSystem("cameraPan", { focusPriority = T.number, position = T.XyPair }, function(e, _)
+cameraPanSystem = world:filteredSystem("cameraPan", { focusPriority = T.number, position = T.XyPair }, function(e, _)
     if e.focusPriority >= focusPriority.priority then
         focusPriority.position = e.position
     end
@@ -21,35 +24,13 @@ function cameraPanSystem.preProcess()
 end
 
 function cameraPanSystem:postProcess()
-    Camera.pan.x = math.max(0, focusPriority.position.x - 200)
-    Camera.pan.y = math.min(0, focusPriority.position.y - 120)
-    -- TODO: set draw offset
+    camera.pan.x = math.max(0, focusPriority.position.x - 200)
+    camera.pan.y = math.min(0, focusPriority.position.y - 120)
+    love.graphics.translate(0, -camera.pan.y)
 
-    for _, entity in pairs(expireBelowScreenSystem.entities) do
-        if entity.position.y - (Camera.pan.y + 240) > entity.expireBelowScreenBy then
+    for _, entity in pairs(expireBelowScreen.entities) do
+        if entity.position.y - (camera.pan.y + 240) > entity.expireBelowScreenBy then
             self.world:removeEntity(entity)
         end
     end
 end
-
-local cameraTopIsh, cameraBottomIsh
-
-local enableNearCameraY = filteredSystem(
-    "enableNearCameraY",
-    { enableNearCameraY = Arr(T.Entity) },
-    function(e, _, system)
-        if e.position.y > cameraTopIsh and e.position.y < cameraBottomIsh then
-            for _, enable in ipairs(e.enableNearCameraY) do
-                enable.velocity = e.velocity
-                system.world:addEntity(enable)
-            end
-            system.world:removeEntity(e)
-        end
-    end
-)
-
-local within = 1000
-function enableNearCameraY:preProcess()
-    cameraTopIsh = Camera.pan.y - within
-    cameraBottomIsh = Camera.pan.y + 240 + within
-end
diff --git a/systems/collision-detection.lua b/systems/collision-detection.lua
index 47b2203..971f5c9 100644
--- a/systems/collision-detection.lua
+++ b/systems/collision-detection.lua
@@ -1,4 +1,6 @@
-collidingEntities = filteredSystem("collidingEntitites", {
+local world = require("world")
+
+local collidingEntities = world:filteredSystem("collidingEntitites", {
     position = T.XyPair,
     size = T.XyPair,
     canCollideWith = T.BitMask,
@@ -19,14 +21,14 @@ local function intersects(rect, rectOther)
     return leftOther < right and left < rightOther and topOther < bottom and top < bottomOther
 end
 
-filteredSystem(
+world:filteredSystem(
     "collisionDetection",
     { position = T.XyPair, size = T.XyPair, canBeCollidedBy = T.BitMask, isSolid = Maybe(T.bool) },
--- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
+    -- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
     function(e, _, system)
         for _, collider in pairs(collidingEntities.entities) do
             if
-            (e ~= collider)
+                (e ~= collider)
                 and collider.canCollideWith
                 and e.canBeCollidedBy
                 and bit.band(collider.canCollideWith, e.canBeCollidedBy) ~= 0
diff --git a/systems/collision-resolution.lua b/systems/collision-resolution.lua
index 4a54df7..aee3f58 100644
--- a/systems/collision-resolution.lua
+++ b/systems/collision-resolution.lua
@@ -1,4 +1,6 @@
-filteredSystem("collisionResolution", { collisionBetween = T.Collision }, function(e, _, system)
+local world = require("world")
+
+world:filteredSystem("collisionResolution", { collisionBetween = T.Collision }, function(e, _, system)
     local collidedInto, collider = e.collisionBetween[1], e.collisionBetween[2]
     system.world:removeEntity(e)
 end)
diff --git a/systems/decay.lua b/systems/decay.lua
index c8581e6..efa12ad 100644
--- a/systems/decay.lua
+++ b/systems/decay.lua
@@ -1,15 +1,17 @@
-filteredSystem("decay", { decayAfterSeconds = T.number }, function(e, dt, system)
+local world = require("world")
+
+world:filteredSystem("decay", { decayAfterSeconds = T.number }, function(e, dt, system)
     e.decayAfterSeconds = e.decayAfterSeconds - dt
     if e.decayAfterSeconds <= 0 then
         system.world:removeEntity(e)
     end
 end)
 
-LiveForNFrames = filteredSystem("liveForNFrames", { liveForNFrames = T.number }, function(e, _, system)
+LiveForNFrames = world:filteredSystem("liveForNFrames", { liveForNFrames = T.number }, function(e, _, system)
     e.liveForNFrames = e.liveForNFrames - 1
     if e.liveForNFrames <= 0 then
         system.world:removeEntity(e)
     end
 end)
 
-LiveForNFrames.deferToEnd = true
\ No newline at end of file
+LiveForNFrames.deferToEnd = true
diff --git a/systems/draw.lua b/systems/draw.lua
index 538e689..01b8f15 100644
--- a/systems/draw.lua
+++ b/systems/draw.lua
@@ -1,3 +1,4 @@
+local world = require("world")
 local gfx = love.graphics
 
 ---@generic T
@@ -5,7 +6,7 @@ local gfx = love.graphics
 ---@param process fun(entity: T, dt: number, system: System) | nil
 ---@return System | { entities: T[] }
 local function drawSystem(name, shape, process)
-    local system = filteredSystem(name, shape, process, function(_, a, b)
+    local system = world:filteredSystem(name, shape, process, function(_, a, b)
         if a.z ~= nil and b.z ~= nil then
             return a.z < b.z
         end
diff --git a/systems/gravity.lua b/systems/gravity.lua
index fbd1879..557709e 100644
--- a/systems/gravity.lua
+++ b/systems/gravity.lua
@@ -1,16 +1,17 @@
+local world = require("world")
 local min = math.min
 
-World:addEntity({ gravity = -300 })
+world:addEntity({ gravity = -300 })
 
-local gravities = filteredSystem("gravities", { gravity = T.number })
+local gravities = world:filteredSystem("gravities", { gravity = T.number })
 
-filteredSystem("changeGravity", { changeGravityTo = T.number }, function(e, _, _)
+world:filteredSystem("changeGravity", { changeGravityTo = T.number }, function(e, _, _)
     for _, ge in pairs(gravities.entities) do
         ge.gravity = e.changeGravityTo
     end
 end)
 
-filteredSystem("fall", { velocity = T.XyPair, mass = T.number }, function(e, dt)
+world:filteredSystem("fall", { velocity = T.XyPair, mass = T.number }, function(e, dt)
     for _, ge in pairs(gravities.entities) do
         e.velocity.y = min(400, e.velocity.y - (ge.gravity * dt * e.mass) - (0.5 * dt * dt))
     end
diff --git a/systems/input.lua b/systems/input.lua
index 747f45d..7bffc43 100644
--- a/systems/input.lua
+++ b/systems/input.lua
@@ -1,7 +1,9 @@
+local world = require("world")
+
 ---@type KeyState
 local keyState = {}
 
-local keyInputSystem = filteredSystem("keyInput", { canReceiveKeys = T.marker }, function(e, _, system)
+local keyInputSystem = world:filteredSystem("keyInput", { canReceiveKeys = T.marker }, function(e, _, system)
     e.keyState = keyState
     system.world:addEntity(e)
 end)
@@ -22,7 +24,7 @@ function ClearKeyState()
     end
 end
 
-local mouse = filteredSystem("mouse", { mouseKeyPress = { position = T.XyPair, key = T.number } })
+local mouse = world:filteredSystem("mouse", { mouseKeyPress = { position = T.XyPair, key = T.number } })
 
 function MouseJustPressed(key, clear)
     clear = clear ~= nil and clear or true
@@ -30,7 +32,7 @@ function MouseJustPressed(key, clear)
         if event.mouseKeyPress and event.mouseKeyPress.key == key then
             if clear then
                 event.mouseKeyPress = nil
-                World:removeEntity(event)
+                world:removeEntity(event)
             end
             return true
         end
@@ -45,7 +47,7 @@ function love.mousemoved(x, y)
 end
 
 function love.mousepressed(x, y, key)
-    World:addEntity({
+    world:addEntity({
         mouseKeyPress = {
             position = {
                 x = x,
diff --git a/systems/velocity.lua b/systems/velocity.lua
index 53b1298..9b4207f 100644
--- a/systems/velocity.lua
+++ b/systems/velocity.lua
@@ -1,6 +1,7 @@
+local world = require("world")
 local sqrt = math.sqrt
 
-filteredSystem("velocity", { position = T.XyPair, velocity = T.XyPair }, function(e, dt, system)
+world:filteredSystem("velocity", { position = T.XyPair, velocity = T.XyPair }, function(e, dt, system)
     if sqrt((e.velocity.x * e.velocity.x) + (e.velocity.y * e.velocity.y)) < 2 then
         -- velocity = nil
     else
@@ -9,8 +10,8 @@ filteredSystem("velocity", { position = T.XyPair, velocity = T.XyPair }, functio
     end
 end)
 
-filteredSystem("drag", { velocity = T.XyPair, drag = T.number }, function(e, dt, system)
+world:filteredSystem("drag", { velocity = T.XyPair, drag = T.number }, function(e, dt, system)
     local currentDrag = e.drag * dt
     e.velocity.x = e.velocity.x - (e.velocity.x * currentDrag * dt)
     e.velocity.y = e.velocity.y - (e.velocity.y * currentDrag * dt)
-end)
\ No newline at end of file
+end)
diff --git a/tiny-debug.lua b/tiny-debug.lua
index 793663a..c1c0956 100644
--- a/tiny-debug.lua
+++ b/tiny-debug.lua
@@ -39,4 +39,4 @@ if tinyWarnWhenNonDataOnEntities then
             return valType
         end
     end
-end
\ No newline at end of file
+end
diff --git a/tiny-tools.lua b/tiny-tools.lua
deleted file mode 100644
index df8c85c..0000000
--- a/tiny-tools.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-local tiny = require("lib/tiny")
-
----@generic T
----@param shape T | fun()
----@param process fun(entity: T, dt: number, system: System) | nil
----@param compare nil | fun(system: System, entityA: T, entityB: T): boolean
----@return System | { entities: T[] }
-function filteredSystem(name, shape, process, compare)
-    assert(type(name) == "string")
-    assert(type(shape) == "table" or type(shape) == "function")
-    assert(process == nil or type(process) == "function")
-
-    local system = compare and tiny.sortedProcessingSystem() or tiny.processingSystem()
-    system.compare = compare
-    system.name = name
-    if type(shape) == "table" then
-        local keys = {}
-        for key, value in pairs(shape) do
-            local isTable = type(value) == "table"
-            local isMaybe = isTable and value.maybe ~= nil
-
-            if not isMaybe then
-                -- ^ Don't require any Maybe types
-                keys[#keys + 1] = key
-            end
-        end
-        system.filter = tiny.requireAll(unpack(keys))
-    elseif type(shape) == "function" then
-        system.filter = shape
-    end
-    if not process then
-        return World:addSystem(system)
-    end
-    function system:process(e, dt)
-        process(e, dt, self)
-    end
-    return World:addSystem(system)
-end
diff --git a/tiny-types.lua b/tiny-types.lua
index 205f198..1e20f82 100644
--- a/tiny-types.lua
+++ b/tiny-types.lua
@@ -46,3 +46,10 @@ function World:getSystemCount() end
 --- the order in which they Systems processed, because lower indexed Systems are
 --- processed first. Returns the old system.index.
 function World:setSystemIndex(world, system, index) end
+
+---@generic T
+---@param shape T | fun()
+---@param process fun(entity: T, dt: number, system: System) | nil
+---@param compare nil | fun(system: System, entityA: T, entityB: T): boolean
+---@return System | { entities: T[] }
+function World:filteredSystem(name, shape, process, compare) end
diff --git a/world.lua b/world.lua
new file mode 100644
index 0000000..b1c85cf
--- /dev/null
+++ b/world.lua
@@ -0,0 +1,2 @@
+local tiny = require("lib/tiny")
+return tiny.world()