Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I really dont understand what it really even is. Is it just normal scripting or something else?
Lua is a fairly well known and often embedded scripting language.
However, if you're after some basic "getting starting" information on Roblox scripting, check out the Roblox Wiki. (The tutorial's section would probably be of specific interest.)
Lua is a well known scripting and programming language that is lightweight and easy to learn. Many games have embedded it, including Garry's Mod (GMod) and World of Warcraft.
ROBLOX uses Lua to actually create games. Most of the features you see in ROBLOX (like the GUI and building tools) are actually coded in Lua.
I'd recommend seeing games by Anaminus, VolcanoINC and Telamon to see what you could do with Lua.
Lua is a scripting language somewhat similar to Java. Infact, I recall there being a Javalua blend as a scripting language in itself. Lua is probably the easiest scripting language to learn and work with. Its functions are fired by changes specified such as script.Parent.Value.Changed:connect(functionnamehere)
Parents are what the script or item specified is in.
Variables work like this:
v = script.Parent.Value
or
d = game.Workspace.ScriptFireValue.Value
If a ROBLOX Solo Game is the source and v's script.Parent's name (script.Parent.Name) is ScriptFireValue then v is equal to d.
The language also includes loops that are recognizable like
lua: while true do
vbs: do while/Loop
java: do while
'for' is a limited loop where it only loops for a certain amount of times.
exe.
for i = 1, 10 do
game.Lighting.TimeofDay = game.Lighting.TimeofDay + 1
end
This part of the script will run 10 times before passing on. when u have the part 1 - 10 or 1, 10.
The 'end' comes after anything highlighted in blue.
Things highlighted will be:
for [whatever's in here will not be highlighted] do - Both words only count for one end.
while true do
while [Something in here that exists or is a value] do - Both words only count for one end.
function()
if [something exists or is a value] then - Both words only count for one end.
else -- Used when the if statement before it is false. When used the 'if' and the 'else' count for one end.
elseif -- Used when the if statement before it is false but also calls for another if statement. When used the 'if' and the 'elseif' count for one end.
I think a few more.
Here's an example script I'm writing off the top of my head. The source I'm going off of is ROBLOX's Build/Edit mode in-game.
function KillAllPlayers(clicker)
if clicker.Name == "coolboy10000" then
people = game.Players:GetChildren()
for i = 1, #people do
people[i].Character.Humanoid.Health = people[i].Character.Humanoid.Health - 10000
end -- ends if
end -- ends for - do
end -- ends function
script.Parent.Clicked:connect(KillAllPlayers)
That script if not obvious identified the player who clicked. (clicker). Btw the argument 'clicker' would be identified the cause of the function to be fired. So the cause is because a button was 'Clicked'. So 'clicker' retrieves the person who initiated that. Therefore identifying if the player is a certain person which would allow the process to continue. So if the player's name is coolboy10000 then it will gather all the players and kill them each.
To put a security on that button to where if the player is not coolboy10000 then the player will be killed you could do this:
function KillAllPlayers(clicker)
if clicker.Name == "coolboy10000" then
people = game.Players:GetChildren()
for i = 1, #people do
people[i].Character.Humanoid.Health = people[i].Character.Humanoid.Health - 10000
end -- ends for - do
else
clicker.Humanoid.Health = clicker.Humanoid.Health - 10000
end -- ends if and else
end -- ends function
script.Parent.Clicked:connect(KillAllPlayers)
If there are multiple people to allow to do this function you could do:
function KillAllPlayers(clicker)
if clicker.Name == "coolboy10000" or "coldnature" then
people = game.Players:GetChildren()
for i = 1, #people do
people[i].Character.Humanoid.Health = people[i].Character.Humanoid.Health - 10000
end -- ends for - do
else
clicker.Humanoid.Health = clicker.Humanoid.Health - 10000
end -- ends if and else
end -- ends function
script.Parent.Clicked:connect(KillAllPlayers)
Or if there is a specific person who should have a separate punishment:
function KillAllPlayers(clicker)
if clicker.Name == "coolboy10000" or "coldnature" then
people = game.Players:GetChildren()
for i = 1, #people do
people[i].Character.Humanoid.Health = people[i].Character.Humanoid.Health - 10000
end -- ends for - do
elseif clicker.Name == "Person299" then
clicker.Head.Position = clicker.Torso.Position
else
clicker.Humanoid.Health = clicker.Humanoid.Health - 10000
end -- ends if and else and elseif - then
end -- ends function
script.Parent.Clicked:connect(KillAllPlayers)
Yeah that's just the basics :/
There are tutorials out there. Mostly on ROBLOX free models. I say you should study some free scripts and learn how they work and stuff. This is just the basics. There is a tutorial on ROBLOX. Just search in Free Models scripting tutorials. Some dude wrote in scripts how to script. It's pretty long to read but that's how I learned.
Roblox is a gaming website where the users make the games using "Roblox Studio". It's almost like a super complex virtual Lego. To interact with your parts(anything in your game) you make scripts that are written in the language "Lua".
Roblox Lua is Lua 5.1 in Roblox's Data Model.
Roblox Lua Scripting is the act of writing in a script in Roblox Studio.
Their scripts are actually objects with embedded code inside of them. They're placed inside of roblox's basic data model and are used for creating and controlling objects, data, and therefore game-play.
I will not repeat what others have said, and say something else instead.
Unlike vanilla lua, ROBLOX lua (also known as rlua) is a modified version of lua.
ROBLOX has implemented different kinds of c and l closures such as tick, wait, delay, and so on, which is why it is a modified version of lua.
Roblox Lua scripting is an embedded coding language to add features to your game. It is easy to learn and is a loose interpretation of modern day game programming. Its an overall great language and I highly recommend it!
https://roblox.fandom.com/wiki/Project:Home
https://devforum.roblox.com/
Related
I'm pretty new to scripting but I'm trying to make a lobby system. Basically when players join they are assigned to the 4 dummies (so 4 players max). So the dummies look like the players. I'm getting very confused looking at the Roblox documentation followed by little scripting experience experience.
I want to:
First delete any dummys that are already loaded
Assign players to the dummies as they join then remove dummies as they leave
Duplicate the dummies from replicated storage and parent them to the Workspace.
Just looking for some guidance please don't write an entire script as I'm trying to use this as a learning tool.
Hers the code so far and now my head hurts haha
local function characterRig()
for i,player in pairs(game.Players:GetPlayers()) do
local dummy = game.ServerStorage["Dummy"..i]
player.CharacterAutoLoads = false
player.Character = dummy
local playerHumanoid = player.Character.humanoid
playerHumanoid:GetHumanoidDescriptionFromUserId()
dummy.Parent = workspace
end
end
game.Players.PlayerAdded:Connect(characterRig)
game.Players.PlayerRemoving:Connect(characterRig)
I am trying to make a script, in Lua code, that detects the level of lighting in my game. I am pretty new to Lua so as far as I know lighting in the game is a number (2, 10, 5).
if game:GetService("Lighting").Brightness < 1 then
game.StarterGui.ScreenGui.output.Text = "You are getting cold";
end
I am not sure if it is just not detecting game:GetService("lighting").Brightness as a number or if the game does not know what game.StarterGui.ScreenGui.output.Text is. I've testing this multiple times, making small alteration every time, but most of the time I got no error. With the code now there is no error message.
Do not use game.StarterGui.
StarterGui is what gui is put inside a player's PlayerGui when they join. Players do NOT see StarterGui.
Instead:
game.Players.PlayerAdded:Connect(function(plr)
if game:GetService("Lighting").Brightness < 1 then
plr.PlayerGui.ScreenGui.output.Text = "You are getting cold";
end
end)
(player).PlayerGui is the gui the player sees. StarterGui will not auto update or modify the game's players' guis when it is changed.
If you have any more questions feel free to ask them with a comment! ^-^
Roblox lua documentation:
https://www.developer.roblox.com/en-us
The overview is I am prototyping code to understand my problem space, and I am running into 'PANIC: unprotected error in call to Lua API (not enough memory)' errors. I am looking for ways to get around this limit.
The environment bottom line is Torch, a scientific computing framework that runs on LuaJIT, and LuaJIT runs on Lua. I need Torch because I eventually want to hammer on my problem with neural nets on a GPU, but to get there I need a good representation of the problem to feed to the nets. I am (stuck) on Centos Linux, and I suspect that trying to rebuild all the pieces from source in 32bit mode (this is reported to extend the LuaJIT memory limit to 4gb) will be a nightmare if it works at all for all of the libraries.
The problem space itself is probably not particularly relevant, but in overview I have datafiles of points that I calculate distances between and then bin (i.e. make histograms of) these distances to try and work out the most useful ranges. Conveniently I can create complicated Lua tables with various sets of bins and torch.save() the mess of counts out, then pick it up later and inspect with different normalisations etc. -- so after one month of playing I am finding this to be really easy and powerful.
I can make it work looking at up to 3 distances with 15 bins each (15x15x15 plus overhead), but this only by adding explicit garbagecollection() calls and using fork()/wait() for each datafile so that the outer loop will keep running if one datafile (of several thousand) still blows the memory limit and crashes the child. This gets extra painful as each successful child process now has to read, modify and write the current set of bin counts -- and my largest files for this are currently 36mb. I would like to go larger (more bins), and would really prefer to just hold the counts in the 15 gigs of RAM I can't seem to access.
So, here are some paths I have thought of; please do comment if you can confirm/deny that any of them will/won't get me outside of the 1gb boundary, or will just improve my efficiency within it. Please do comment if you can suggest another approach that I have not thought of.
am I missing a way to fire off a Lua process that I can read an arbitrary table back in from? No doubt I can break my problem into smaller pieces, but parsing a return table from stdio (as from a system call to another Lua script) seems error prone, and writing/reading small intermediate files will be a lot of disk i/o.
am I missing a stash-and-access-table-in-high-memory module ? This seems like what I really want, but not found it yet
can FFI C data structures be put outside the 1gb? Doesn't seem like that would be the case but certainly I lack a full understanding of what is causing the limit in the first place. I suspect that this will just get me an efficiency improvement over generic Lua tables for the few pieces that have moved beyond prototyping? (unless I do a bunch of coding for each change)
Surely I can get out by writing an extension in C (Torch appears to support nets that should go outside of the limit), but my brief investigation there turns up references to 'lightuserdata' pointers -- does this mean that a more normal extension won't get outside 1gb either? This also seems like it has the heavy development cost for what should be a prototyping exercise.
I know C well so going the FFI or extension route doesn't bother me - but I know from experience that encapsulating algorithms in this way can be both really elegant and really painful with two places to hide bugs. Working through data structures containing tables within tables on the stack doesn't seem great either. Before I make this effort I would like to be certain that the end result really will solve my problem.
Thanks for reading the long post.
Only object allocated by LuaJIT itself are limited to the first 2GB of memory. This means that tables, strings, full userdata (i.e. not lightuserdata), and FFI objects allocated with ffi.new will count towards the limit, but objects allocated with malloc, mmap, etc. are not subjected to this limit (regardless if called by a C module or the FFI).
An example for allocating a structure with malloc:
ffi.cdef[[
typedef struct { int bar; } foo;
void* malloc(size_t);
void free(void*);
]]
local foo_t = ffi.typeof("foo")
local foo_p = ffi.typeof("foo*")
function alloc_foo()
local obj = ffi.C.malloc(ffi.sizeof(foo_t))
return ffi.cast(foo_p, obj)
end
function free_foo(obj)
ffi.C.free(obj)
end
The new GC to be implemented in LuaJIT 3.0 IIRC will not have this limit, but I haven't heard any news on it's development recently.
Source: http://lua-users.org/lists/lua-l/2012-04/msg00729.html
Here is some follow-up information for those who find this question later:
The key information is as posted by Colonel Thirty Two, that C module extensions and FFI code can easily get outside of the limit. (and the referenced lua list post reminds that plain Lua tables that go outside the limit will be very slow to garbage collect)
It took me some time to pull the pieces together to both access and save/load my objects, so here it is in one place:
I used lds at https://github.com/neomantra/lds as a starting point, in particular the 1-D Array code.
This broke using torch.save(), as it doesn't know how to write the new objects. For each object I added the code below (using Array as the example):
function Array:load(inp)
for i=1,#inp do
self._data[i-1] = tonumber(inp[i])
end
return self
end
function Array:serialize ()
local siz = tonumber(self._size)
io.write(' lds.ArrayT( ffi.typeof("double"), lds.MallocAllocator )( ', siz , "):load({")
for i=0,siz-1 do
io.write(string.format("%a,", self._data[i]))
end
io.write("})")
end
Note that my application specifically uses doubles and malloc(), so a better implementation would store and use these in self rather than hard coding above.
Then as discussed in PiL and elsewhere, I needed a serializer that would handle the object:
function serialize (o)
if type(o) == "number" then
io.write(o)
elseif type(o) == "string" then
io.write(string.format("%q", o))
elseif type(o) == "table" then
io.write("{\n")
for k,v in pairs(o) do
io.write(" ["); serialize(k); io.write("] = ")
serialize(v)
io.write(",\n")
end
io.write("}\n")
elseif o.serialize then
o:serialize()
else
error("cannot serialize a " .. type(o))
end
end
and this needs to be wrapped with:
io.write('do local _ = ')
serialize( myWeirdTable )
io.write('; return _; end')
and then the output from that can be loaded back in with
local myWeirdTableReloaded = dofile('myWeirdTableSaveFile')
See PiL (Programming in Lua book) for dofile()
Hope that helps someone!
You can use the torch tds module. From the README:
Data structures which do not rely on Lua memory allocator, nor being limited by Lua garbage collector.
Only C types can be stored: supported types are currently number, strings, the data structures themselves (see nesting: e.g. it is possible to have a Hash containing a Hash or a Vec), and torch tensors and storages. All data structures can store heterogeneous objects, and support torch serialization.
This addon for world of warcraft written in lua can track quest up to 6 levels lower than the current level om my character, and show them on the map.
The creator of this addon stated in a forum that we can change this to show all quests that are lower than the current character level by just changing the code in the files.
I have tried and tried with different numbers and operators, but I am not a programmer, I have not goten it to work as I want to, so I turn here for a helping hand.
How do I change this line of code to show me all quest lower than my characters level on the in game map?
function Questie:addAvailableQuests()
local mapid = getCurrentMapID();
local level = UnitLevel("Player");
for l=level-6,level do --this line
I agree with Egor but it could be:
for l=1,level do --this line
As LUA has 1-based indexing and I imagine the rest of the code uses the l counter as the index of the quest list. If that doesn't work please post the rest of the function. I would comment above but I do not have above 50 rep yet.
I'm porting FFT code from Java to Lua, and I'm starting to worry a bit about the fact that in Lua the array part of a table starts indexing at 1 while in Java array indexing starts at 0.
For the input array this causes no problem because the Java code is set up to handle the possibility that the data under consideration is not located at the start of the array. However, all of the working arrays internal to the code are assumed to starting indexing at 0. I know that the code will work as written -- Lua tables are awesome like that -- but I have no sense at all about the performance hit I might incur by having the "0" element of the array going into the hash table part of the underlying C structure (or indeed, if that is what will happen).
My question: is this something worth worrying about? Should I be planning to profile and hand-optimize the code? (The code will eventually be used to transform many relatively small (> 100 time points) signals of varying lengths not known in advance.)
I have made small, probably not that reliable, test:
local arr = {}
for i=0,10000000 do
arr[i] = i*2
end
for k, v in pairs(arr) do
arr[k] = v*v
end
And similar version with 1 as the first index. On my system:
$ time lua example0.lua
real 2.003s
$ time lua example1.lua
real 2.014s
I was also interested how table.insert will perform
for i=1,10000000 do
table.insert(arr, 2*i)
...
and, suprisingly
$ time lua example2.lua
real 6.012s
Results:
Of course, it depends on what system you're running it, probably also whic lua version, but it seems that it makes little to no difference between zero-start and one-start. Bigger difference is caused by the way you insert things to array.
I think the correct answer in this case is changing the algorithm so that everything is indexed with 1. And consider that part of the conversion.
Your FFT will be less surprising to another Lua user (like me), given that all "array-like" tables are indexed by one.
It might not be as stressful as you might think, given the way numeric loops are structured in Lua (where the "start" and the "end" are "inclusive"). You would be exchanging this:
for i=0,#array-1 do
... (do stuff with i)
end
By this:
for i=1,#array do
... (do stuff with i)
end
The non-numeric loops would remain unchanged (except that you will be able to use ipairs too, if you so desire).