Self Generating Obby

What is this?

So a couple of weeks ago I made a self-generating obby system, "Not a self-generating stage system". I posted it on Twitter and got positive comments. I love to help people when I can, and I love it when people help me. I have now tested this publicly in 1.5 weeks and it works as it should.

Why did I make this?

Back in "2016, 2017, 2018" I spent hundreds of hours making obbies by hand. When I made this system I thought about how many hours of my life I could’ve saved by making it automated. Now that I have an ok understanding in scripting I decided to make this. It works and is uploaded in a place for anyone to take.

Image of the generation system in action.

What is included in the system?

  • Marketplace System, for gamepasses & devproducts. (Tools, Skip Stage)
  • Chat Tag System. (Custom tag for players that are in the “Developers” table)
  • Sound System with noises for different types of events. (Death, Purchase, UI Click &, etc)
  • Checkpoint System.
  • No Player Collision System.
  • Badge Awarding System.
  • Custom Loading Screen.
  • And some more useful systems on the client.

How to use:

It should be alright to use if you have decent knowledge in LUA. It is also important to be structured due to the color customization of this system and generation or else the system will warn you and not work.

Where to change stage colors?:
“ServerScriptService > Server > Obby” and the name of the variables are RandomColorOne and RandomColorTwo.

Where to change stage amount?:
“ServerScriptService > Server > Settings > Stages” and then change the value to how many stages you want.

image

Where to add new stages and how to define lava parts?:
“ServerStorage > Stages > All” and that is where the stages should be located. You also have to make sure that every stage has the part under the checkpoint as PrimaryPart.

The last stage is called Finish and it is under “ServerStorage > Stages”

Lava parts must be placed inside a Lava folder inside the model. The parts of the obby also have to be structured in the folder “One” and “Two” under “Colored”. You’ll understand if you take a look at the stages in Workspace.

What is Turnpoint?:
“ServerScriptService > Server > Settings > Turnpoint” is an IntValue I made that will eventually turn the stages, so it doesn’t always go in a straight line. If your obby goes in a straight line, then I’d recommend to change it up a bit. A value between 1 to 25 should mostly be fine.

Do you have to give credit?

Short answer, no. I would recommend changing the settings frame because I and my friend are credited. There is no need to credit us! You can also feel free to use the GFX that I bought for this!

I had to cover a lot in this and let me know if there is something I forgot to say! Use this as you wish and good luck with your obby! :star:

Download:

Preview of Generation Code:

Main
local ObbyService = {}

-- SERVICES
local ServerStorage = game:GetService("ServerStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")

-- MODULES
local GenerationService = require(ServerScriptService.Server.Obby:WaitForChild("Generation"))

-- VARIABLES
local RNG = Random.new()
local Settings = {
	Stages = script.Parent.Settings:WaitForChild("Stages").Value,
	Turnpoint = script.Parent.Settings:WaitForChild("Turnpoint").Value
}
local globalCount = 1
local count = Settings.Stages
local direction = true

-- FUNCTIONS
function ObbyService:GenerateObby()
	for currentCount = 1, count, 1 do wait(0.3)
		local RandomColorOne, RandomColorTwo = Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255)), Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255))
		local Stage = GenerationService:GetRandomStage()
		if not Stage then return end
		if globalCount == Settings.Stages then -- if stage end
			GenerationService:CreateStage(Stage, globalCount, RandomColorOne, RandomColorTwo, nil, true)
			globalCount = globalCount + 1
			break
		elseif currentCount % Settings.Turnpoint == (Settings.Turnpoint * 0.8) then -- turn stage
			if direction then
				direction = false
				for live = 1, Settings.Turnpoint, 1 do wait(0.3)
					if globalCount == Settings.Stages then break end
					local RandomColorOne, RandomColorTwo = Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255)), Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255))
					Stage = GenerationService:GetRandomStage()
					GenerationService:CreateStage(Stage, globalCount, RandomColorOne, RandomColorTwo, 90, false)
					globalCount = globalCount + 1
				end
			else
				direction = true
				for live = 1, Settings.Turnpoint, 1 do wait(0.3)
					if globalCount == Settings.Stages then break end
					local RandomColorOne, RandomColorTwo = Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255)), Color3.fromHSV(RNG:NextInteger(1, 360), RNG:NextInteger(1, 255), RNG:NextInteger(1, 255))
					Stage = GenerationService:GetRandomStage()
					GenerationService:CreateStage(Stage, globalCount, RandomColorOne, RandomColorTwo, -90, false)
					globalCount = globalCount + 1
				end
			end
		else -- normal stage
			GenerationService:CreateStage(Stage, globalCount, RandomColorOne, RandomColorTwo, nil, false)
			globalCount = globalCount + 1
		end
	end
end

-- CONNECTIONS
spawn(function()
	ObbyService:GenerateObby()
end)

return ObbyService
Secondary
local GenerationService = {}

-- SERVICES
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local CollectionService = game:GetService("CollectionService")
local ServerStorage = game:GetService("ServerStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")

-- VARIABLES
local StagePlacement = game.Workspace:WaitForChild("Stages")
local CheckpointPlacement = game.Workspace:WaitForChild("Checkpoints")
local Stages = ServerStorage:WaitForChild("Stages")
local StageStorage = Stages:WaitForChild("All")
local Children = StageStorage:GetChildren()
local Previous
local Connections = {}

-- FUNCTIONS
function GenerationService:GetRandomStage()
	if not Children or #Children < 1 then warn("[SERVER] - Could not find any stages!") return end
	local Stage = tostring(Children[math.random(1, #Children)])
	return Stage
end

function GenerationService:CreateStage(typ, stagNR, one, two, angle, last)
	if not Children or #Children < 1 then warn("[SERVER] - Unable to create stage!") return end
	local Stage
	if not last then
		Stage = StageStorage[typ]:Clone()
	else
		Stage = Stages.Finish:Clone()
	end
	if not Stage:FindFirstChild("Colored") then
		return warn("[SERVER] - " .. typ .. " " .. stagNR .. " failed to get colored!")
	end
	for _, part in pairs(Stage.Colored.One:GetChildren()) do
		if one then
			if part:IsA("BasePart") or part:IsA("WedgePart") or part:IsA("TrussPart") then
				part.Color = one
			end
		end
	end
	for _, part in pairs(Stage.Colored.Two:GetChildren()) do
		if two then
			if part:IsA("BasePart") or part:IsA("WedgePart") or part:IsA("TrussPart") then
				part.Color = two
			end
		end
	end
	
	Stage.Parent = StagePlacement
	
	if Stage:FindFirstChild("Lava") then
		for _, lavaObj in pairs(Stage.Lava:GetChildren()) do
			CollectionService:AddTag(lavaObj, "Lava")
			if one then
				lavaObj.Color = one
				lavaObj.CanCollide = false
			end
			if not lavaObj.Anchored and lavaObj:IsDescendantOf(game.Workspace) then
				lavaObj:SetNetworkOwner(nil)
			end
		end
	end
	if Previous then
		if angle then
			Stage:SetPrimaryPartCFrame(CFrame.new(Previous.Next.Position) * CFrame.Angles(0, math.rad(angle), 0))
		else
			Stage:SetPrimaryPartCFrame(CFrame.new(Previous.Next.Position))
		end
		Previous.Next:Destroy()
	else
		Stage:SetPrimaryPartCFrame(CFrame.new(0, 0, 0))
	end
	
	Previous = Stage
	
	local Checkpoint = Stage.Checkpoint
	if Checkpoint then
		if one then
			Checkpoint.Color = one
		end
		Checkpoint.Name = "Checkpoint " .. stagNR
		Checkpoint.Parent = CheckpointPlacement
		if stagNR == 1 then
			return
		end
	end
end

local function kill(hit)
	local Player = Players:GetPlayerFromCharacter(hit.Parent)
	if Player then
		if hit:IsA("BasePart") and not hit:IsA("Accessory") and Player then
			local Humanoid = Player.Character:FindFirstChild("Humanoid")
			if Humanoid then
				if Humanoid.Health > 0 then
					Humanoid:TakeDamage(100)
				end
			else
				return print("[SERVER] - Character could not be found.")
			end
		end
	end
end

-- CONNECTIONS
CollectionService:GetInstanceAddedSignal("Lava"):Connect(function()
	for _, lavaObj in pairs(CollectionService:GetTagged("Lava")) do
		lavaObj.Touched:Connect(kill)
	end
end)

return GenerationService
149 Likes

Thank you for this amazing open source creation :smiley: I will definitely be using this :slight_smile:

4 Likes

Very curious about the scripts behind it. Thanks for making it open-sourched!

3 Likes

Amazing resource! Thank you for creating this!

1 Like

Appreciate your contribution!
Definitely another good learning point for me.

1 Like

Very cool! Definitely deserves to be a popular obby.

2 Likes

Me: Laughs evilly and makes one hundred Obbies a day with this tool with titles like Escape Piggy Obby [FLAMINGO VISITED].

In all seriousness though, cool resource!

4 Likes

This is super cool. One of the amazing things you can do with scripting.

1 Like

Hey, this idea is very unique. This is very off topic, but how did you make it so your indents have arrows in it? I would like to add this into my studio too!

2 Likes

File > Settings > Studio > Script Editor > Show Whitespace.

I’m not on my computer at the moment, but that should be it.

2 Likes

Very helpful generation code you made!
I’ve never made an obby before but i’m sure that this generation system will be very helpful for obby developers, since it takes a lot of time building a obby map with 100, 200, 500+ stages.
I will definitely try this system out!

Anyways thanks for sharing this!
Sincerely
Veinsson.

2 Likes

Good, now script kiddies can get thousands of robux without 0 effort, Thank you very much!!

I mean no offense but you just gave us every tool to make an successful obby, I mean just someone has to adversite the game and add gamepasses also obbies then boom they have made game that gets players easily, I mean yes making obbies takes a effort but what about, checkpoints? chat tags? skip system? sound system? and more? you basically gave us everything. i love the work but i still dont like the way that people can make robux easily from this. It should take some effort, some time

2 Likes

That is true, but it can be used for good. That is because if someone uses this, and if the obby becomes somewhat successful. It may motivate the person to make more games in general and potentially work on other types of games that aren’t obbies.

2 Likes

I love this source! Definitely going to use it. Thanks for showing us!

1 Like

I might use this someday. :smile: Thank you for making this open sourced!

1 Like

Yeah, I recevied the movitation by a obby game of mine but the thing is i didnt use a framework like this, i coded them all at my own.

1 Like

I only like source code from older games i can revamp, things that show me how to do things, or this, where I can redo a ton of building, and have fun

Hey, am I allowed to use portions of this?

Thanks!

1 Like

You are allowed to use everything. :100:

1 Like

Awesome, thanks for making your creation open source, it’s a great way for others to learn from your work and overall improves the community as a whole. :+1:t2:

2 Likes