Assuming you use TeleportAsync instead of Teleport (you should), you can create a TeleportOptions instance using Instance.new. I also assume that the SpawnLocation is not too special, because this way of doing it is exploitable. A safer but also more complicated way of doing this is using Memory Stores.
Using the first way mentioned, a TeleportOptions instance has two functions you can use to achieve this: GetTeleportData and SetTeleportData.
You would have two spawn point indicating parts. They should be floating, so that people won't get stuck in the middle of the floor. Make sure to anchor them.
You would then have a script calling Player:GetJoinData when they join. If there is relevant data, you should teleport the player to one part, whereas other data would teleport the player to the other part.
In pseudo-code:
players.PlayerAdded:Connect(function(player)
if not player.Character then player.CharacterAdded:Wait() end
local part = workspace.SpawnPartNormal
if player:GetJoinData().TeleportData.TeleportedFromGameA then
part = workspace.SpawnPartFromGameA
end
move_characterof_to(player, part)
end)
The safer way of doing it will unfortunately not work if the two places are not of the same experience (game). Here is the safer way:
local store = memorystoreserv:GetSortedStore("PlayerFromGameA")
players.PlayerAdded:Connect(function(player)
if not player.Character then player.CharacterAdded:Wait() end
local part = workspace.SpawnPartNormal
if store:GetAsync(player.UserId) then
part = workspace.SpawnPartFromGameA
end
move_characterof_to(player, part)
end)
Both of these are nearly identical. In the safer one, I used a MemoryStoreSortedMap object's GetAsync function.