|
| 17 Jan 2016 10:46 PM |
Assuming you've already played Phantom Forces (PF), you've noticed the game uses a chunk loading system that is virtually lagless.
Say I wanted to create a similar system, that loads a map over time, speed pertaining to the computer and internet of the player, that creates next to no lag at all,
where would I start?
Any suggestions on how I would load my map so that it not only doesn't lag, but also loads the map in a somewhat fast way?
Examples and explanations appreciated thanks |
|
|
| Report Abuse |
|
|
| |
|
|
| 17 Jan 2016 10:59 PM |
| at least one of you has to know |
|
|
| Report Abuse |
|
|
| |
|
|
| 17 Jan 2016 11:19 PM |
| this is ending up as one of those posts you bump forever and ever without a response |
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
|
| 17 Jan 2016 11:20 PM |
I have absolutely no idea...
But I'd probably attempt to load like, 100 parts at a time, and then wait a short moment, idk.
Honestly, when I have loaded maps, I was able to load over 1000 parts nearly instantly without any issues whatsoever... And that was before featherweight existed.
I think I've heard of some people storing maps in scripts, (like tables of all relevant values and such), and then it's unpacked... (I think that was more useful if you had many many maps, back when 10,000 parts could cause lag).
|
|
|
| Report Abuse |
|
|
|
| 17 Jan 2016 11:25 PM |
| well, im loading it from the client, and i want to load it so well that it would only take a matter of seconds, but at the same time not cause any background audio to become scratchy, or slow the speed of cursor movement |
|
|
| Report Abuse |
|
|
|
| 17 Jan 2016 11:26 PM |
| http://forum.roblox.com/Forum/ShowPost.aspx?PostID=181895149 |
|
|
| Report Abuse |
|
|
|
| 17 Jan 2016 11:33 PM |
@iJacobness i dont want that, i want a chunk loading script or explanation that works perfectly
|
|
|
| Report Abuse |
|
|
|
| 17 Jan 2016 11:42 PM |
The smallest amount of time you could take to do what you want to do is...
Make a list of all parts in a given chunk Each part's properties will be recorded (color, position, etc), but anything that defaults to the same as Instance.new("Part") won't be recorded, as you can assume that there is no change. You would then iterate over and only add X amount of parts per second. |
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
|
| 17 Jan 2016 11:43 PM |
Yeah, idk...
Maybe do some crazy math... If every part in your map is in one model, perhaps...
local model = game.(wherever your stuff is) local container = Instance.new("Model") container.Parent = game.Workspace
local parts = model:GetChildren() for i=1, math.ceil(#parts/250) do wait(0.5) for d=1, 250 do if parts[d+((i-1)*250)] ~= nil then parts[d+((i-1)*250)].Parent = container end end end
Honestly, I've got no idea if something like that would work, I've got a headache and it's nearly midnight... But, I think the concept is what's important. I don't know if this would load the map without issues... And if you want to load in via the client, then I guess you'd be using a local script... (And I guess you'll want to use ReplicatedStorage, although, I've been gone so long I haven't touched that yet).
But, what I'm trying to do is:
Every half second, 250 parts are parented from the storage to the workspace, or in other words, "loaded". I guessed at the math, but I was trying to run the first for loop a number of times equal to how many parts are in the map divided by 250. I used math.ceil() to round that number up. So, 950 parts would mean the loop is run 4 times.
I'm hoping my check if the part is nil or not will prevent it from erroring on the 951st part in a situation like that... In 5 years, I can't recall a time I ever didn't know the size of a table. (It's probably possible to only run it the exact amount, but eh).
[d+((i-1)*250)]
Well... i-1 would mean that i is 0 for the first iteration, and 0*250 is 0, so, we start at d, which is 1-250. Then, when i is 2, we have (2-1) = 1, 1*250 = 250, 250+d = 251-500, and so on and so forth. Maybe.
The forum link that person posted... I am sure that method works perfectly fine at first glance, but I noticed wait() was used in between each part... Well, if you have 2000 parts in your map, then it'll take over a minute to run... (Idk, did roblox update to 60fps, and is wait() == wait(1/60), or is it still 1/30?) Regardless, that'd take way too long, so I think you'll need to load multiple parts in the same frame, rather than 1...
My code is just a crude, most likely broken, concept of how to do that. |
|
|
| Report Abuse |
|
|
|
| 17 Jan 2016 11:49 PM |
| I wonder if it is more expensive to take parts out of a storage and to have these parts in memory over creating new parts when you need them. |
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
|
| 17 Jan 2016 11:59 PM |
With featherweight making anchored parts almost negligible... It might work better just to keep the parts stored... And for all we know, the storage options ROBLOX has provided us actually do the same thing, by converting the parts into memory and then loading them when needed, especially with how they've changed the format for storing places and parts. (They use patterns and the whole binary system thing or something instead of XML, so game places save and load a lot faster).
Honestly, with how featherweight works, you could probably just have all maps loaded initially... I guess when you enter the place, initially, it'd take a few seconds longer... But even 50,000 parts loads pretty fast these days. Just keep vision of other maps blocked out somehow, and poof... |
|
|
| Report Abuse |
|
|
|
| 18 Jan 2016 12:03 AM |
i just want something smooth and fast, but something that works with the speed at which the player is working with
|
|
|
| Report Abuse |
|
|
|
| 18 Jan 2016 12:04 AM |
| If roblox supported dynamic models rather than the static 6*2 faced part, a lot of things would be easier. |
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
|
| 18 Jan 2016 12:08 AM |
@OriginalPoster(OP),
If you use a method like the one I showed you, I think you'd be happy with the results.
But, you'll probably need to figure out the nuances yourself.
Since you have control of your place, you could even model together groups of say, 200 parts, and then name them each, "Chunk", and then iterate through every Chunk inside of the Map model, and load it as a whole...
local container = Instance.new("Model") container.Name = "Container" contrainer.Parent = game.Workspace local mapChunks = game.ServerStorage.mapChunks
for i=1, #mapChunks do if mapChunks[i].ClassName == "Model" then local parts = mapChunks[i]:GetChildren() for d=1, #parts do parts[d].Parent = container end end end
|
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
|
| 18 Jan 2016 12:08 AM |
local container = Instance.new("Model") container.Name = "Container" contrainer.Parent = game.Workspace local mapChunks = game.ServerStorage.mapChunks
for i=1, #mapChunks do wait(0.5) if mapChunks[i].ClassName == "Model" then local parts = mapChunks[i]:GetChildren() for d=1, #parts do parts[d].Parent = container end end end
Forgot to put a wait in there, haha... |
|
|
| Report Abuse |
|
|
|
| 18 Jan 2016 12:16 AM |
| its alright im going to try my own method |
|
|
| Report Abuse |
|
|
|
| 18 Jan 2016 12:31 AM |
-- this is my attempt
local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LoadedBaseParts = {}
local function GatherParts(Object, Table) for _, Child in next, Object:GetChildren() do if Child:IsA("BasePart") then table.insert(Table, Child) elseif #Child:GetChildren() > 0 then GatherParts(Child, Table) end end return Table end
local function Preload(InitialModel, BaseModel) LoadedBaseParts[InitialModel] = GatherParts(BaseModel, {}) return LoadedBaseParts[InitialModel] end
local function LoadMap(InitialModel, BaseModel, Activated) local Count = 0 local Parts = {} for _, Part in next, (Activated and (LoadedBaseParts[InitialModel] or Preload(InitialModel, BaseModel)) or GatherParts(InitialModel, {})) do Count = Count + 1 table.insert(Parts, Part) if Count >= 20 then Count = 0 for _, Child in next, Parts do if Activated then Child:clone().Parent = InitialModel else Child:Destroy() end end RunService.RenderStepped:wait() Parts = {} end end if not Activated then InitialModel:ClearAllChildren() end end
Preload(workspace.Model, ReplicatedStorage.Model) LoadMap(workspace.Model, ReplicatedStorage.Model) LoadMap(workspace.Model, ReplicatedStorage.Model, true) |
|
|
| Report Abuse |
|
|
SunTzu16
|
  |
| Joined: 10 Jul 2012 |
| Total Posts: 999 |
|
| |
|
|
| 18 Jan 2016 01:12 AM |
| it works. properly though? idk |
|
|
| Report Abuse |
|
|
| |
|
|
| 18 Jan 2016 07:17 AM |
Do this
-- have models inside this with a few parts in them, no more than 50 parts i guess, maybe even less
function loadMap(map, mapHolder) local model = Instance.new("Model") model.Name = "Map" model.Parent = mapHolder for i, chunk in pairs (map:GetChildren()) do chunk:clone().Parent = model print(tostring((i / #map:GetChildren()) * 100) .. "%") wait() end end |
|
|
| Report Abuse |
|
|