local C=game:GetService("\082\117\110\083\101\114\118\105\099\101")local J=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local E=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local l=E.Packages local f=require(E.Lib.Matter)local T=require(l.plasma)local w=(require(l.rewire)).HotReloader local Z=require(script.Parent.components)local function D(E)local l=f.World.new()local D={}local Q=f.Debugger.new(T)Q.findInstanceFromEntity=function(C)if not l:contains(C)then return end local J=l:get(C,Z.Model)return J and J.model or nil end local j=f.Loop.new(l,D,Q:getWidgets())j:setWorlds({World=l})local r=w.new()local X={}local s={}local function A(C,J)local E=J.originalModule local l,f=pcall(require,C)if not l then warn("\069\114\114\111\114 \119\104\101\110 \104\111\116-\114\101\108\111\097\100\105\110\103 \115\121\115\116\101\109",C.name,f)return end if X then table.insert(X,f)elseif s[E]then j:replaceSystem(s[E],f)Q:replaceSystem(s[E],f)else j:scheduleSystem(f)end s[E]=f end local function R(C,J)if J.isReloading then return end local E=J.originalModule if s[E]then j:evictSystem(s[E])s[E]=nil end end for C,J in E do r:scan(J,A,R)end j:scheduleSystems(X)X=nil Q:autoInitialize(j)j:begin({default=C.Heartbeat;Stepped=C.Stepped})if C:IsClient()then J.InputBegan:Connect(function(C)if C.KeyCode==Enum.KeyCode.F4 then Q:toggle()D.debugEnabled=Q.enabled end end)end return l,D end return D
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage.Packages
local Matter = require(ReplicatedStorage.Lib.Matter)
local Plasma = require(Packages.plasma)
local HotReloader = require(Packages.rewire).HotReloader
local components = require(script.Parent.components)

local function start(containers)
	local world = Matter.World.new()
	local state = {}

	local debugger = Matter.Debugger.new(Plasma)

	debugger.findInstanceFromEntity = function(id)
		if not world:contains(id) then
			return
		end

		local model = world:get(id, components.Model)

		return model and model.model or nil
	end

	local loop = Matter.Loop.new(world, state, debugger:getWidgets())
	loop:setWorlds({ World = world })

	-- Set up hot reloading

	local hotReloader = HotReloader.new()

	local firstRunSystems = {}
	local systemsByModule = {}

	local function loadModule(module, context)
		local originalModule = context.originalModule

		local ok, system = pcall(require, module)

		if not ok then
			warn("Error when hot-reloading system", module.name, system)
			return
		end

		if firstRunSystems then
			table.insert(firstRunSystems, system)
		elseif systemsByModule[originalModule] then
			loop:replaceSystem(systemsByModule[originalModule], system)
			debugger:replaceSystem(systemsByModule[originalModule], system)
		else
			loop:scheduleSystem(system)
		end

		systemsByModule[originalModule] = system
	end

	local function unloadModule(_, context)
		if context.isReloading then
			return
		end

		local originalModule = context.originalModule
		if systemsByModule[originalModule] then
			loop:evictSystem(systemsByModule[originalModule])
			systemsByModule[originalModule] = nil
		end
	end

	for _, container in containers do
		hotReloader:scan(container, loadModule, unloadModule)
	end

	loop:scheduleSystems(firstRunSystems)
	firstRunSystems = nil

	debugger:autoInitialize(loop)

	-- Begin running our systems

	loop:begin({
		default = RunService.Heartbeat,
		Stepped = RunService.Stepped,
	})

	if RunService:IsClient() then
		UserInputService.InputBegan:Connect(function(input)
			if input.KeyCode == Enum.KeyCode.F4 then
				debugger:toggle()

				state.debugEnabled = debugger.enabled
			end
		end)
	end

	return world, state
end

return start
