How do players experience my game?

I have my game,

and I need to fix it.

By fixing it I mean that the user experience might not be the best, the monetization, game flow/loops, etc.

The game is a generic tycoon. You can get all the floors, rebirth, get a multiplier, and redo it all over again. Pretty repetitive. Already I can see why not many people play it. I will be rewriting the code at some point, and when doing so, I will need to know what the best way to rebirth is so you don’t get bored. Do I not even have rebirths at all?

There are also many other things. Parkour courses, cocoa, meteorite, etc. Quests are coming soon which can probably give the player something to do.

I’d love for some constructive criticism regarding anything. Maybe some gamepasses are too high of a price.

If you reply, thanks for your feedback.

1. The Tutorial:

The tutorial seems complicated. I would recommend using a tutorial system like this script that you would need to apply to your game yourself:

LocalScript, StarterGui.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local HasTycoon = false
local Attachment = Instance.new("Attachment")
Attachment.Parent = Character:WaitForChild("HumanoidRootPart")

for _, Tycoons in pairs(game:GetService("Workspace").Tycoons:GetChildren()) do
	if HasTycoon then return end
	if not Tycoons:GetAttribute("TycoonClaimed") then -- I used an attribute for this. Where is the attribute or bool value of checking if the tycoon is claimed or not. .OnClientEvent:Connect(function()
		local Beam = script.ArrowEffect:Clone() -- For this, you will need to add a Beam effect. I added the properties below to be an arrow.
		Beam.Attachment0 = Attachment
		Beam.Attachment1 = Tycoons.Door -- Where is the claim door of the tycoon? Also, add an Attachment to each one.
		Beam.Parent = Character.HumanoidRootPart
		ReplicatedStorage. Whatever remote event that fires the client when their tycoon is claimed.
			Beam.Enabled = false
			HasTycoon = true
		end)

		Tycoons:GetAttributeChangedSignal("TycoonClaimed"):Connect(function() -- Once again, attribute. You can use a Changed signal.
			print("TycoonAddedOrRemoved")
			if not HasTycoon then
				if Tycoons:GetAttribute("TycoonClaimed") then
					Beam.Enabled = false
				else
					Beam.Enabled = true
				end
			end
		end)
	end
end

The effect for the Beam:
Color = Make it whatever color you want, but make it bright.
Texture = rbxassetid://5886559421
TextureLength = 1
TextureMode = Static (Recommended)
TextureSpeed = 1 (Recommended, but you can do whatever)
Transparency = 0.3 Recommended
FaceCamera = true (RECOMMENDED)

2. The re-play value:

In my opinion, there is no re-play value, which will make players not come back. This looks like an average tycoon from 2016.

Yea. I would try to make it a game kind of like Retail Tycoon or Theme Part Tycoon when you are re-writing it. It might take a while to do that, but I would recommend watching @zblox164 's tutorial of his build mode tycoon:

(Do not use @zblox164’s system of saving and loading. Use mine (This one is old, but it should get the job done. It has other things such as Town data and other things. This game never released.

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("HouseSaving")
local PlayerId = -1

game:GetService("Players").PlayerAdded:Connect(function(plr)
	if PlayerId == -1 then
		PlayerId = plr.UserId
		game.ReplicatedStorage.TownData:SetAttribute("TownOwner", plr.UserId)
		print("Town owner created")
	end
end)

local function Save()
	local TableToSave = {}
	for _, Item in pairs(script.Parent.itemHolder:GetChildren()) do
		--table.insert(TableToSave, {ItemName = Item.Name, ItemCFrame = tostring(Item:GetPrimaryPartCFrame())})

		table.insert(TableToSave, {
			["ItemName"] = Item.Name,
			["Position"] = {Item.PrimaryPart.Position.X, Item.PrimaryPart.Position.Y, Item.PrimaryPart.Position.Z, Item.PrimaryPart.Orientation.X, Item.PrimaryPart.Orientation.Y, Item.PrimaryPart.Orientation.Z}
		})
	end
	local Success, Save = pcall(function()
		DataStore:SetAsync(PlayerId, TableToSave)
	end)
	if Success then
		print("It worked!!!")
	else
		warn("Failed to save.")
		print([[The Error: 
		]].. tostring(Save))
	end
end

local function Load()
	local Data

	local Success, Load = pcall(function()
		Data = DataStore:GetAsync(PlayerId)
		print(PlayerId)
	end)

	if not Success then
		warn("Failed to load.")
		print([[The Error:
		]].. tostring(Load))
		game:GetService("Players"):GetPlayerByUserId(PlayerId):Kick("Error Code 2 - Failed to load Townmasters data. Please check the main menu to see if your Townmasters Data is corrupted.")
	else
		for _, Items in pairs(Data) do
			--local Clone = game:GetService("ReplicatedStorage").ReplicatedFurnitureModels[table.find(Data, "ItemName")]:Clone()
			--Clone:SetPrimaryPartCFrame(table.find(Data, "ItemCFrame"))
			local ItemName = "ItemName"
			local ItemCFrame = "ItemCFrame"
			local Clone = game:GetService("ReplicatedStorage").ReplicatedFurnitureModels[Items[ItemName]]:Clone()
			Clone:PivotTo(CFrame.new(Items["Position"][1], Items["Position"][2], Items["Position"][3])*CFrame.fromEulerAnglesXYZ(math.rad(Items["Position"][4]), math.rad(Items["Position"][5]), math.rad(Items["Position"][6])))
			Clone.Parent = workspace.base.itemHolder
		end
	end
end

game:GetService("Players").PlayerAdded:Connect(function(plr)
	if PlayerId == nil then
		PlayerId = plr.UserId
		Load()
	end
end)

game.ReplicatedStorage.Save.Event:Connect(Save)

Now, when making a sandbox tycoon, you might want to do something like what I am doing:
image
This will attract players on specific days and have them only come for the buff. My system is automatic btw (Using os.date and os.time for the MST time zone.)

  1. Show UI like this every day you wish to buff (I did Friday and Saturday because it will attract more players to this.)

  2. Make sure it is easy to understand.

  3. Make sure the whole system works.


That is all I have for making CFT a better game. Also, I would refund older players their money, and try to use DataStore2 for reliability (Especially my saving method because it uses SetAsync, which is horrible for saving data.)

5 Likes

Hey @IAmPinleon , I’ve tested the game for a couple minutes and it’s pretty good. I like that there are obstacle courses to keep the players more interested.

The color in the game looks way too saturated and the shadows is way too dark, I suggest adding some fog/atmosphere to keep up to date with the lighting.

I also discover a bug when the UIs are clipping into each other. And it’s pretty annoying to get rid off.

1 Like

Do not use either for real game purposes. My system should work fine in testing as yours should as well, however for a more secure option, I recommend reading this tutorial: DataStores - Beginners to Advanced and adapting my system for it. Little things I didn’t include in this series such as using GetRequestBudgetForRequestType() to improve saving/loading instead of using a repeat loop or using UpdateAsync() (which is better overall) are included in this tutorial (not my series).

My series is only meant to give the basic instructions on how such a game may be created not give the most optimized/secure methods.

2 Likes