Cloning a model with server scripts from LocalScript?

Is it not possible to clone a model via a Localscript, and the model contains a local script? Does the local script not fire? Like is anything in the workspace only server sided scripts can be run?

Basically, I’m making a Zombie game. And to really make the encounters and what not unique I wanted to make zombies locally for x player in x region. But is this not possible?

2 Likes

no. you can serialize it through remoteevents, but its recommended to put it in replicatedStorage , to be easier and better

So it’s not possible to essentially create client sided NPC’s?

It should be possible to clone local scripts and make them run as long as they’re parented to the right instance and are enabled.

I’m gonna test that.

Even if you can’t, there are definitely workarounds, like module scripts.

Edit: It works.

2 Likes

It is. Its possible

just if you handle the localscript in playergui instead of workspace it should work fine.

Ah, what I was doing is I had a local script inside a model. And via a GUI / Mouseclick I parented the model to workspace with the local script inside. In this instance it doesn’t work?

Because localscripts only run in playerbased instances like:

PlayerGui
Backpack
PlayerScripts
Character
etc

Personally, I would go for PlayerScripts, but pick one of these instances which is the most practical or the most you like.

Edit: Or a much better solution, use @goldenstein64 method of using modulescripts and requiring them in PlayerScripts.

1 Like

What benefit is a module script? Isn’t that just for storing static data essentially?

if you want to easily run a “localscript” in a character you can require with the instance arg

Sorry I’m a tad confused here. So you’re saying I need to require a module script (which runs a local script)

you dont need to. its optional, im saying put the modulescript inside your instance and require it in playerscripts, but make sure to put instance arg.

Whenever you require a module script, you’re also running all the code in the module script.

For example,

in some local script:

local npc = -- your npc

require(npc.RunScript)

and in your npc’s RunScript (which is a module script):

print("hello world!")

print("look at all this stuff I'm doing")

return nil

Your local script would start running all the code in the module script, which would make it print "hello world!", etc.

Edit: The caveat / advantage is that the code in your module script only runs once no matter how many times you require it.

The NPC’s runscript in this case is a local script right?

1 Like

No, this is just a module script. Sorry, I should’ve specified that!

Ah but what can you do with a module script? I thought you could only really store data in that? Like

x = {}

x.y = 5

return x

And then be able to require data?
Like how am I to make a functioning NPC from a script that can only run once?

Or are you guys just giving an example of how to use module scripts in the event that I’m creating an NPC in this case locally.

I guess I was under the impression you were talking about creating the entire NPC ai via module scripts.

You can definitely create an NPC using just module scripts, and you can use the method I was talking about too.

e.g. same local script:

local npc = -- your npc

require(npc.RunScript)

and the npc’s RunScript (which is still a module script):

local Players = game:GetService("Players")

local NPC = script.Parent

local humanoid = NPC:WaitForChild("Humanoid")

local function getNearestTarget()
    -- I don't feel like writing that, 
    -- but it returns the nearest player
end

-- this is wrapped in a coroutine so that it doesn't yield forever.
local followLoop = task.defer(function()
    while true do
        local target = getNearestTarget()

        local targetRoot = target.Character.HumanoidRootPart
        humanoid:MoveTo(targetRoot.Position)

        task.wait(0.5)
    end
end)

humanoid.Died:Connect(function()
    task.cancel(followLoop)

    -- tell the humanoid to stop moving
    humanoid:Move(Vector3.new(0, 0, 0))
end)

return nil

The first time you require the RunScript module is the moment all this code gets executed.

There are other ways to structure the module if you don’t like doing it like this, like putting all this code in some functions in a table and returning the table so that the local script can run all the logic.

2 Likes

Ok cool, 2 more questions.

#1) WHat is task.defer do?

#2) If I’m to make some sort of detection for lets say bullets. Like I’ve got a gun that creates bullets locally. Would a simple part.touched event run if the bullet and the part are both local parts?

  1. task.defer runs the inner function argument in the very near future, like 0.001 seconds in the future, and lets that code run at the same time as other code. task.spawn does the same thing but runs the inner function first until it yields (via task.wait, event:Wait(), or an Async / WaitForChild method).

  2. That would work if the bullet is fired slowly enough, but I wouldn’t recommend it. I would use raycasting. You can either write the raycasts yourself or use a module like FastCast.

2 Likes

So is task.defer essentially what you’d use when you don’t want to have to call the function? And that’s also cool that you can cancel (in the death event)

Would you be able to give me an example of a raycast from x part → player mouse.hit?

Thanks.

task.defer / task.spawn is what you’d use when you want to run a function at the same time as everything else. I still want to call the function, I just don’t want it to only run the stuff in the function. I want it to do the stuff after it too.

Here’s an Intro to Raycasting tutorial from the Dev Hub, It should answer most of your questions. You don’t really have to pay attention to the code snippets, reading the normal text should be enough.

And your example I guess:

local Workspace = game:GetService("Worksapce")

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = { --[[ player's character ]] }

local function raycast(xPart: BasePart, mouseHit: CFrame): RaycastResult
    local origin = xPart.Position
    local direction = mouseHit.Position - xPart.Position
    local result = Workspace:Raycast(origin, direction, rayParams)

    return result
end

result is of type RaycastResult (Dev Hub) (New Docs).

1 Like