EasyML - An easy way to use machine learning in your Roblox games!

Oh yeah I know why, try with these training data instead:

local trainingData = {
    {0, 0},  -- Forward obstacle detected
    {0, 1},  -- Backward obstacle detected
    {1, 0},  -- Right obstacle detected
    {1, 1},  -- Left obstacle detected
}

well it now works but still result always 1 im going to see why by printing (I can also give code again)

1 Like

so since the action is choosing 1 it will always go forward but since (my testing place might be different) the table has {1 = 1, 2 = 0, 3 = 1, 4 = 0)

1 Like

but it doesnt do the action probably because the action that is on because its 1. is there a way to fix that?

1 Like

Yeah, you could use the key instead of the value and keep the value as a debugging info (most likely by printing the key and the value in the output).

so like this?

 actionNumber == # and actionIndex == #
1 Like

btw that from a for loop. Because I think that would work

1 Like

Code:

local RS = game:GetService("ReplicatedStorage")
local Modules = require(RS:WaitForChild("Modules").Modules)
local machineLearning = Modules.MachineLearningModule
local nn_model = machineLearning.new(machineLearning.ModelType.NeuralNetwork)
local dt_model = machineLearning.new(machineLearning.ModelType.DecisionTree)

local NPC = workspace:WaitForChild("NPCFolder"):WaitForChild("tracedrounds")
local humanoid = NPC:FindFirstChildWhichIsA("Humanoid")
local humanoidRootPart = humanoid.RootPart

-- Define constants
local NUM_INPUTS = 4 -- Number of directions to consider
local NUM_HIDDEN = 48
local NUM_OUTPUTS = 4 -- For actions: move forward, move backward, turn left, turn right
local EPOCHS = 1000
local LEARNING_RATE = 0.1
local DEBUG_MODE = false

-- Example training data for the neural network
local trainingData = {
	{0, 0},  -- Forward obstacle detected
	{0, 1},  -- Backward obstacle detected
	{1, 0},  -- Right obstacle detected
	{1, 1},  -- Left obstacle detected
}

local trainingTargets = {
	{1}, -- Move forward
	{2}, -- Move backward
	{3}, -- Turn left
	{4}, -- Turn right
}

-- Initialize Neural Network model
nn_model:train({}, trainingTargets, {
	numInputs = NUM_INPUTS,
	numHidden = NUM_HIDDEN,
	numOutputs = NUM_OUTPUTS,
	epochs = EPOCHS,
	learningRate = LEARNING_RATE,
	debugMode = DEBUG_MODE
})

-- Define obstacle detection function
local function detectObstacles()
	local obstacles = {}
	local directions = {
		{ direction = humanoidRootPart.CFrame.LookVector, name = "forward" },
		{ direction = -humanoidRootPart.CFrame.LookVector, name = "backward" },
		{ direction = humanoidRootPart.CFrame.RightVector, name = "right" },
		{ direction = -humanoidRootPart.CFrame.RightVector, name = "left" }
	}
	for _, dir in ipairs(directions) do
		local ray = Ray.new(humanoidRootPart.Position, dir.direction * 10)

		local params = RaycastParams.new()
		params.RespectCanCollide = true
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = {NPC}

		local result = workspace:Raycast(humanoidRootPart.Position, dir.direction * 10, params)
		if result then
			table.insert(obstacles, _)
		else
			table.insert(obstacles, 0)
		end
	end
	return obstacles
end

-- Define action functions
local function moveForward()
	humanoid:MoveTo(humanoidRootPart.Position + humanoidRootPart.CFrame.LookVector * 5)
end

local function moveBackward()
	humanoid:MoveTo(humanoidRootPart.Position - humanoidRootPart.CFrame.LookVector * 5)
end

local function turnLeft()
	humanoidRootPart.CFrame = humanoidRootPart.CFrame * CFrame.Angles(0, math.rad(-90), 0)
end

local function turnRight()
	humanoidRootPart.CFrame = humanoidRootPart.CFrame * CFrame.Angles(0, math.rad(90), 0)
end

-- Function to choose action using the neural network model
local function chooseAction(obstacles)
	-- Predict action based on obstacles
	local output = nn_model:predict(obstacles)
	
	print(output)
	
	local actions = output
	
	
	for actionNumber, actionIndex in ipairs(actions) do
		-- Execute action
		if actionNumber == 1 and actionIndex == 1 then
			moveForward()
		elseif actionNumber == 2 and actionIndex == 1 then
			moveBackward()
		elseif actionNumber == 3 and actionIndex == 1 then
			turnLeft()
		elseif actionNumber == 4 and  actionIndex == 1 then
			turnRight()
		end
		
		continue
	end
	
	
end

-- Main loop
while true do
	local obstacles = detectObstacles()
	chooseAction(obstacles)
	wait(1) -- Adjust as needed for your game
end
1 Like

also sorry for showing code so much, I just want you (and maybe some other people to see the issue)

1 Like

Well, I would recommend using table.concat and then using string.gmatch() to be able to use each one of these keys separately.
(you can also check out this post as it contains relevant information about this function)

So it would look like this:

local actionKey = table.concat(action, ", ")

for action in string.gmatch(actionKey, ",") do 
		-- Execute action
		if actionNumber == 1 and actionIndex == 1 then
			moveForward()
		elseif actionNumber == 2 and actionIndex == 1 then
			moveBackward()
		elseif actionNumber == 3 and actionIndex == 1 then
			turnLeft()
		elseif actionNumber == 4 and  actionIndex == 1 then
			turnRight()
		end
		
		continue
end

(Sorry if the format is kinda messed up it’s hard to do tabs on phone)

No problem, it helps so it’s fine!

well, it is working but still but not moving just rotating I can give my place file real quick I just have to make a new one (I don’t like doing originals)

wait nevermind I just realized your on phone.

I can do recording. would that be okay so you see the output.

1 Like

Yeah sure, so I can see how is the npc rotating too

Diagram:

The dot is the NPC if you didn’t know

the bottom ->. is what actually happening

It is moving but it doesn’t. For some reason

local RS = game:GetService("ReplicatedStorage")
local Modules = require(RS:WaitForChild("Modules").Modules)
local machineLearning = Modules.MachineLearningModule
local nn_model = machineLearning.new(machineLearning.ModelType.NeuralNetwork)
local dt_model = machineLearning.new(machineLearning.ModelType.DecisionTree)

local NPC = workspace:WaitForChild("NPCFolder"):WaitForChild("tracedrounds")
local humanoid = NPC:FindFirstChildWhichIsA("Humanoid")
local humanoidRootPart = humanoid.RootPart

-- Define constants
local NUM_INPUTS = 4 -- Number of directions to consider
local NUM_HIDDEN = 48
local NUM_OUTPUTS = 4 -- For actions: move forward, move backward, turn left, turn right
local EPOCHS = 1000
local LEARNING_RATE = 0.1
local DEBUG_MODE = false

-- Example training data for the neural network
local trainingData = {
	{0, 0},  -- Forward obstacle detected
	{0, 1},  -- Backward obstacle detected
	{1, 0},  -- Right obstacle detected
	{1, 1},  -- Left obstacle detected
}

local trainingTargets = {
	{1}, -- Move forward
	{2}, -- Move backward
	{3}, -- Turn left
	{4}, -- Turn right
}

-- Initialize Neural Network model
nn_model:train({}, trainingTargets, {
	numInputs = NUM_INPUTS,
	numHidden = NUM_HIDDEN,
	numOutputs = NUM_OUTPUTS,
	epochs = EPOCHS,
	learningRate = LEARNING_RATE,
	debugMode = DEBUG_MODE
})

-- Define obstacle detection function
local function detectObstacles()
	local obstacles = {}
	local directions = {
		{ direction = humanoidRootPart.CFrame.LookVector, name = "forward" },
		{ direction = -humanoidRootPart.CFrame.LookVector, name = "backward" },
		{ direction = humanoidRootPart.CFrame.RightVector, name = "right" },
		{ direction = -humanoidRootPart.CFrame.RightVector, name = "left" }
	}
	for _, dir in ipairs(directions) do
		local ray = Ray.new(humanoidRootPart.Position, dir.direction * 10)

		local params = RaycastParams.new()
		params.RespectCanCollide = true
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = {NPC}

		local result = workspace:Raycast(humanoidRootPart.Position, dir.direction * 10, params)
		if result then
			table.insert(obstacles, 1)
		else
			table.insert(obstacles, 0)
		end
	end
	return obstacles
end

-- Define action functions
local function moveForward()
	humanoid:MoveTo(humanoidRootPart.Position + humanoidRootPart.CFrame.LookVector * 5) --humanoid:MoveTo(humanoidRootPart.Position + humanoidRootPart.CFrame.LookVector * 5)
end

local function moveBackward()
	humanoid:MoveTo(humanoidRootPart.Position - humanoidRootPart.CFrame.LookVector * 5) --humanoid:MoveTo(humanoidRootPart.Position - humanoidRootPart.CFrame.LookVector * 5)
end

local function turnLeft()
	humanoidRootPart.CFrame = humanoidRootPart.CFrame * CFrame.Angles(0, math.rad(-90), 0)
end

local function turnRight()
	humanoidRootPart.CFrame = humanoidRootPart.CFrame * CFrame.Angles(0, math.rad(90), 0)
end

-- Function to choose action using the neural network model
local function chooseAction(obstacles)
	-- Predict action based on obstacles
	local output = nn_model:predict(obstacles)	
	local actions = output
	
	print(output)	
	
	for actionNumber, actionIndex in ipairs(actions) do
		
		local action = actionIndex
		local actionKey = table.concat(actions, ", ")

		for action in string.gmatch(actionKey, ",") do 
			-- Execute action
			if actionNumber == 1 and actionIndex == 1 then
				moveForward()
				continue
			elseif actionNumber == 2 and actionIndex == 1 then
				moveBackward()
				continue
			elseif actionNumber == 3 and actionIndex == 1 then
				turnLeft()
				continue
			elseif actionNumber == 4 and  actionIndex == 1 then
				turnRight()
				continue
			end
		end
		
	end
	
	
end

-- Main loop
while true do
	local obstacles = detectObstacles()
	chooseAction(obstacles)
	task.wait()
end

do you know the error?

1 Like

What about OpenML? Roblox is a more front-end game, why should people use this over OpenML? It’s not like this isn’t the backend. I might not be saying this correctly.

1 Like