Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

I have the over all idea for script but how would I run it efficiently?

Asked by 8 years ago

Here's the story. I have created a mining game (yes I know there are to many of them already but that's not the point) but I am having trouble with making a seemingly infinite mine. I have made a script that checks through a bunch of Vector3 values every time someone tries to mine. It checks if the position next to the block being mined is one of the Vector3Values and if it isn't, then it creates a block there and put's it's position among the Vector3Values. There are six sides to a block so it has to check for six different values in several hundred Vector3Values. At the moment, this system works but it is not very efficient and is taxing on the server (run on a standard server script). I have asked others about this before and they said to spawn in the blocks when a player is near them and de-spawn once the player is far enough away. How might I do this efficiently with a bunch of different players on the server and fast enough that if a player is falling through a mine, it doesn't create lag or latency? I am not asking for a script but an idea for it that can be built upon. I hope to have a final system with similar efficiency as The Quarry or Epic Mining 2.

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

I'm going to distill your problem down to something simple:

You have a list of things (Vector3s), and you want to quickly know whether a given v is in that list.

Your current solution -- compare it to everything in the list -- is called linear search (linear because you check all of them in the line of the list). If you have 100, this will take 100.

Ideally you could ask directly whether or not a container contains what you want. You can use dictionaries to do this -- dictionaries don't get slower when you put more things in them -- so it will be very fast1. Note that Vector3s themselves can't be the key of the dictionary (for technical reasons2) but you can use something like tostring on them to produce keys:

local rockLocations = {}

-- use as such:
local v = Vector3.new(10, 10, 20)
local p = Instance.new("Part", workspace)
p.CFrame = CFrame.new(v)
--
rockLocations[ tostring(v) ] = p

Or just true instead of p if you don't need to keep track of what is at that location (but you probably do)

Note that this will only work nicely if all of your vector3s have integers for x y and z.

A Module Script

If you have a bunch of scripts that need to be able to use this data, you could use a ModuleScript to share.

A simple way to make this work is just make the module script return the empty table object:

return {}

Every script that requires this module will get the same table -- any change any one makes, all of them see that change. Note: This won't share between Script and LocalScripts, or LocalScripts for different players.

A better thing to do would be to make get and put functions so that your script using the module don't have to worry about just using Vector3 values:

local r = {}

-- e.g., assuming you're on a 4x4x4 grid, this will return the object
-- at position v even if `v` isn't perfectly on the grid
-- (e.g.,  0.23, 0.58, 1.87 will mean the first cell (0,0,0) and 6.83, 3.9, 38.0 will mean (1, 0, 0))
local function key(v)
    local kx, ky, kz = math.floor(v.x / 4), math.floor(v.y / 4), math.floor(v.z / 4)
    return kx .. "," .. ky .. "," .. kz
end

function r:get(v)
    return r[ key(v) ]
end

function r:put(v, obj)
    r[key(v)] = obj
end

return r

  1. on average. 

  2. Keys are compared essentially using rawget; two Vector3s at the same position in the world are different objects so they will be put in different places in the dictionary. Strings or numbers don't have that problem -- when == is true they are also the same object (which is actually quite remarkable for strings) 

0
Wow, I didn't know you could use tables like that. I thought you could only reference them as table[position] not table[key]. This will help out with this and TONS of other problems. Thank you so much! BobserLuck 367 — 8y
0
Is there a way that the table can be used by multiple scripts but still be the one table? I know I can make it a global variable but I'd rather not do that. Is there a way to do it with module scripts? BobserLuck 367 — 8y
0
I'll edit my answer to explain how to do that BlueTaslem 18071 — 8y
Ad

Answer this question