Undocumented functions, documented
Posted: Sat Mar 19, 2016 10:57 am
How:
Result:User scripts can freely overwrite these values if they like. Want to change the result of multiplying two vectors, even when it happens internally? You can! I don't recommend it though. Remember that such a change won't be serialized, so you need to do it every time the game is reloaded (easy to do in an init file).
Here are the ones you didn't know about:
GameMode.getEnableControls(), GameMode.setEnableControls(boolean)
Seems extremely similar to
GameMode.setGameFlag("DisableMovement",true)
GameMode.setGameFlag("DisableMouseLook",true)
GameMode.setGameFlag("DisableKeyboardShortcuts",true)
but with a few differences: you can't pick up or throw items with the mouse, you can't open or close champion windows (but if you open a champion window before disabling controls, you can still manipulate items inside the champion window, switch tabs, train skills, etc.), but you can still attack and swap weapon sets with the mouse. Seems safe enough, provided you always remember to enable the controls again when you're done.
GameMode.getTimeMultiplier(), GameMode.setTimeMultiplier(number)
Remember when I guessed that Grimrock 2 probably has a timescale variable, but I didn't know of a way to change it without memory editing? Well, I wasn't lying, I actually didn't know about GameMode.setTimeMultiplier() at the time. But before you add your Time Slow spell, keep in mind that changing timescale in games generally breaks all manner of things, and that may be the reason this function isn't listed in the scripting reference.
math.atan2(number,number)
http://www.cplusplus.com/reference/cmath/atan2/
math.chromacity(vector)
Doesn't work from the user scripting interface, and to be honest, I have no idea what the hell you'd use chromacity for in the first place.
math.clamp(number num,number min,number max)
Returns the equivalent of math.max(min,math.min(max,num)). Note the order of the parameters to math.min and math.max is relevant if you pass in NaN (this is also how I am able to figure it out).
math.cosh
math.isPow2(number)
Returns true if the number is a non-negative integer power of 2, false otherwise.
math.frexp(number)
Returns the significant and exponent of the number (remember, every number in Lua 5.1 is a binary64 floating point). This is actually extremely useful in certain extremely specific situations.
math.ldexp(number num,number exponent)
Returns num*2^exponent.
math.lerp(number a,number b,number c)
math.lerp(vector a,vector b,number c)
math.lerp(matrix a,matrix b,number c)
Returns the linear interpolation of a and b, with c as the "time" - that is, at 0 it returns a, at 1 it returns b, at 0.5 it returns the average of a and b.
math.log10(number)
Returns the logarithm base 10 of the number. I probably didn't need to say that.
math.luminance(vector)
Treats the vector as a color and returns the luminance.
math.map
I honestly have no clue what this does, other than it seems to want numbers or maybe vectors as arguments.
math.nextPow2(number)
Returns the smallest power of 2 that is greater than or equal to the number. Returns 1 if you pass NaN, in case you needed to know that for some insane reason.
math.noise(number)
Returns a number between -0.5 and 0.5, which is the result of a mysterious mostly-smooth function that seems to have a very long period. Note that this function frequently returns 0. Used widely for flickering lights.
math.pow(number x, number e)
Returns x^e, but is slower than just typing x^e, and doesn't work on vectors...
math.saturation(vector,number)
Used in the asset pack. Treats the vector as a color, and returns a vector representing that color with its saturation multiplied by the number. E.g. math.saturation(vec(1,0.5,0),0.8) returns vec(0.918480, 0.518480, 0.118480, 0.000000), and math.saturation(vec(1,0.5,0),0) returns vec(0.592400, 0.592400, 0.592400, 0.000000). Should you give a saturation value greater than 1, the returned vector can include negative numbers.
math.sign(number)
Returns 1 if number is positive, -1 if number is negative, 0 if number is 0 or NaN.
math.sinh(number)
math.smoothstep(number x, number left, number right)
See https://en.wikipedia.org/wiki/Smoothstep, but note the arguments are in a different order than on that page; x is the first argument instead of the last. Seems like it *should* work on vectors but I always get a stack overflow when I try.
math.sqr(number)
math.sqr(vector)
Returns the square of the argument. Useless for numbers (using the ^ or * operator is many times faster than making a function call) but nice to have for vectors.
math.tanh(number)
MersenneTwister stuff
There's really not much of a reason to mess with any of the undocumented fields on this table, unless you just want to cause a crash.
string.camelCaseToUnderscore(string)
("CamelCase DUCK"):camelCaseToUnderscore() returns "camel_case _d_u_c_k".
string.capitalize(string)
Capitalizes the first letter. ("look out! it's a DUCK"):capitalize() returns "Look out! it's a DUCK".
string.count(string str, string search)
Returns the number of times str contains search.
("duckDUCKduckDUCK"):count("duck") returns 2.
If search is the empty string, enters an infinite loop, so don't do that.
string.gfind
The lua wiki doesn't list this on the string library tutorial page for some reason, but it is a standard Lua library function:
http://www.lua.org/pil/20.1.html
string.split(string str, string delimiter)
Returns a table which is str "split" by delimiter.
("123456DUCK789DUCK0123"):split("DUCK") returns {"123456","789","0123"}.
("cat"):split("DUCK") returns {"cat"}.
If delimiter is the empty string, enters an infinite loop, so don't do that.
string.underscoreToCamelCase(string)
("duck_duck_DUCK_duck"):underscoreToCamelCase() returns "duckDuckDUCKDuck".
table.erase(table)
Assigns nil to all keys in the table, turning it into an empty table.
table.contains(table array,object)
Returns true if any of the values in the array are equal to the object, false otherwise. ONLY WORKS ON ARRAYS (tables with consecutive integer keys). Very useful, but remember that this is an O(n) operation.
table.copy(table)
Returns a shallow copy of the table, including the metatable.
table.deepcopy(table)
Returns a "deep" copy of the table, including the metatable. Copying a GameObject, component, Champion, or pretty much anything else that isn't a simple table will produce a bad object that can't be used for anything useful (won't be added to the map and no methods can be used). However, it works for copying matrices and vectors. But keep in mind that GameObject:getWorldPosition() and GameObject:getWorldRotation() already return copies of the vector and matrix.
table.indexOf(table,object)
If any of the values in the array are equal to the object, returns its index, otherwise returns nil. ONLY WORKS ON ARRAYS (tables with consecutive integer keys). Very useful, but remember that this is an O(n) operation.
table.keys(table)
Returns an array of all the keys in the table.
table.values(table)
Returns an array of all the values in the table. Wanted to use table.contains() on a non-array table? If you aren't concerned about performance, you can use table.contains(table.values(tab),object). Of course, the array returned will be unsorted (except for the part of the table that was already an array, if any), so table.indexOf(table.values(tab),object) is not useful.
Set(array)
This global function is equivalent to
vec.__add(vector,vector) or + operator
Adds two vectors together.
vec.__div(vector,number) or / operator
Divides a vector by a scalar. You cannot divide a vector by another vector, and will get a stack overflow if you try.
vec.__index(table,key) or table indexing operator
vec.__newindex(table,key) or assignment operator
The default vec.__index and vec.__newindex make vec.x equivalent to vec[1], vec.y equivalent to vec[2], etc. The default __newindex will raise an error if you try to assign to an index other than 1, 2, 3, 4, "x", "y", "z", or "w".
vec.__mul(vector,vector or number) or * operator
Multiplies two vectors, or multiplies a vector by a number.
vec.sphericalDirection(number azimuthal,number polar)
Returns a vector pointing in the direction indicated by the passed azimuthal and polar angles (both numbers). Example: vec.sphericalDirection(math.pi/2,math.pi/4) will return vec(0,sqrt(2)/2,sqrt(2)/2).
vec.__sub(vector,vector) or binary - operator
Subtracts one vector from another.
vec.__tostring(vector)
Returns the string representation of the vector (what you get when you use the "print" function to print a vector).
vec.__unm(vector) or unary - operator
Returns the unary minus of the vector.
vec.clone(vector)
Returns a copy of the vector.
vec.cross(vector,vector)
Returns the 3D cross product of two vectors (4th dimension is ignored)
vec.dot(vector,vector)
Returns the dot product of two vectors.
vec.isvec(any)
Returns whether the argument is a vector. Since the global type() function can't differentiate between vectors and tables, this is by far the most convenient way to ensure a value is a vector.
vec.length(vector)
Returns the length of a vector, i.e., sqrt(vector[1]^2+vector[2]^2+vector[3]^2+vector[4]^2).
vec.length3(vector)
Returns the length of the vector ignoring the 4th value, so vec.length3(vec(2,2,2,2)) is the same as vec.length(vec(2,2,2,0)).
FUN FACT: This function is used internally by MonsterWarpComponent's visual effect and absolutely nothing else, so you can change this function to mess with the warp effect without breaking anything else.
vec.lengthSquared(vector)
Like length without the sqrt.
vec.lengthSquared3(vector)
Like length3 without the sqrt.
vec.normalize(vector)
Normalizes a vector.
vec.perpendicular(vector)
Returns a vector that is perpendicular to the argument. Assumes the vector is 3D, so the fourth element is ignored and vec.perpendicular(vec(0,1)) returns vec(0,-0,1)
vec.set(vector a,vector b)
Copies the contents of vector b to vector a.
vec.truncate(vector,number length)
Returns a copy of the vector that is truncated so its length does not exceed length. If the vector's length is already at or below length, the copy is identical to the original vector.
Code: Select all
do
local doneTables = {}
local function spaces(indentLevel)
local rval = ""
for i=1,indentLevel do
rval=rval.." "
end
return rval
end
local function printTable(name,t,recurseLevel)
doneTables[t] = true
print(string.format("%s%s = table:",spaces(recurseLevel or 0),name))
recurseLevel = recurseLevel or 1
for key,value in pairs(t) do
if type(value) == "table" then
if doneTables[t] then
print(string.format("%s%s = table: %s",spaces(recurseLevel),tostring(key),tostring(value)))
else
printTable(key,value,recurseLevel+1)
end
else
print(string.format("%s%s = %s",spaces(recurseLevel),tostring(key),tostring(value)))
end
end
end
printTable("Config",Config)
printTable("Console",Console)
printTable("DamageFlags",DamageFlags)
printTable("Dungeon",Dungeon)
printTable("Editor",Editor)
printTable("GameMode",GameMode)
printTable("ItemSlot",ItemSlot)
printTable("MersenneTwister",MersenneTwister)
printTable("Time",Time)
printTable("math",math)
printTable("string",string)
printTable("table",table)
end
Code: Select all
Config = table:
getRenderingQuality = function: 0x00e91d68
getKeyBinding = function: 0x00e91b70
Console = table:
setSuppressWarnings = function: 0x00e91978
warn = function: 0x00e91780
DamageFlags = table:
NoLingeringEffects = 512
Champion2 = 8
HalveBackRowDamage = 128
OngoingDamage = 2
Champion1 = 4
Champion4 = 32
Impact = 1
DamageSourceIceShards = 1024
Champion3 = 16
IgnoreImmunities = 64
CameraShake = 256
Dungeon = table:
getMaxLevels = function: 0x00e92740
getMap = function: 0x00e92548
Editor = table:
isRunning = function: 0x00e92938
GameMode = table:
getGameFlag = function: 0x00e938f8
setEnableControls = function: 0x00e93ee0
setCamera = function: 0x00e92d28
showImage = function: 0x00e94ab0
getEnableControls = function: 0x00e93ce8
completeGame = function: 0x00e95098
setTimeMultiplier = function: 0x00e942d0
playStream = function: 0x00e94ca8
getStatistic = function: 0x00e944c8
getTimeMultiplier = function: 0x00e940d8
setMaxStatistic = function: 0x00e948b8
advanceTime = function: 0x00e93310
playVideo = function: 0x00e94ea0
fadeIn = function: 0x00e93118
fadeOut = function: 0x00e92f20
unlockAchievement = function: 0x00e92b30
getMaxStatistic = function: 0x00e946c0
setTimeOfDay = function: 0x00e93700
setGameFlag = function: 0x00e93af0
getTimeOfDay = function: 0x00e93508
ItemSlot = table:
OffHand2 = 12
Feet = 6
BackpackLast = 32
Weapon2 = 11
Weapon = 1
Gloves = 9
Necklace = 8
MaxSlots = 32
Chest = 4
Head = 3
Bracers = 10
Legs = 5
OffHand = 2
Cloak = 7
BackpackFirst = 13
MersenneTwister = table:
__gc = function: 0x00356e48
baseclass = table: table: 0x00351998
dispose = function: 0x00356e68
isDisposed = function: 0x00356df0
create = function: 0x0035c968
properties = table: table: 0x0035c9e8
__tostring = function: 0x00356e28
type = MersenneTwister
randomInt = function: 0x0035c9a8
random = function: 0x0035c988
__index = table: table: 0x0035c940
Time = table:
systemTime = function: 0x00e91f60
deltaTime = function: 0x00e92158
currentTime = function: 0x00e92350
math = table:
ceil = function: fast#39
tan = function: fast#46
smoothstep = function: 0x00354f70
log10 = function: fast#42
sign = function: 0x00392bf0
sinh = function: fast#50
chromacity = function: 0x00354fe8
ldexp = function: fast#60
huge = inf
atan2 = function: fast#57
min = function: fast#61
fmod = function: fast#59
exp = function: fast#43
random = function: 0x0035ca10
rad = function: fast#56
log = function: fast#41
map = function: 0x00354f88
cos = function: fast#45
clamp = function: 0x00354f40
saturation = function: 0x00355000
mod = function: fast#59
nextPow2 = function: 0x00354fb8
luminance = function: 0x00354fd0
isPow2 = function: 0x00354fa0
randomseed = function: 0x0035ca30
floor = function: fast#38
sqrt = function: fast#40
max = function: fast#62
atan = function: fast#49
noise = function: 0x00396238
acos = function: fast#48
lerp = function: 0x00354f58
abs = function: fast#37
sqr = function: 0x00392bd8
sin = function: fast#44
asin = function: fast#47
frexp = function: fast#53
tanh = function: fast#52
cosh = function: fast#51
modf = function: fast#54
pow = function: fast#58
deg = function: fast#55
pi = 3.1415926535898
string = table:
find = function: fast#86
capitalize = function: 0x00355048
camelCaseToUnderscore = function: 0x00355060
len = function: fast#77
gsub = function: fast#90
upper = function: fast#84
sub = function: fast#80
char = function: fast#79
split = function: 0x00355030
rep = function: fast#81
underscoreToCamelCase = function: 0x00355078
lower = function: fast#83
gmatch = function: fast#89
reverse = function: fast#82
byte = function: fast#78
match = function: fast#87
count = function: 0x00355018
gfind = function: fast#89
format = function: fast#91
table = table:
sort = function: fast#99
keys = function: 0x003550c0
copy = function: 0x00355090
erase = function: 0x00355120
contains = function: 0x00355108
indexOf = function: 0x003550f0
values = function: 0x003550d8
foreach = function: fast#93
maxn = function: fast#95
remove = function: fast#97
foreachi = function: fast#92
deepcopy = function: 0x003550a8
getn = function: fast#94
concat = function: fast#98
insert = function: fast#96
Here are the ones you didn't know about:
GameMode.getEnableControls(), GameMode.setEnableControls(boolean)
Seems extremely similar to
GameMode.setGameFlag("DisableMovement",true)
GameMode.setGameFlag("DisableMouseLook",true)
GameMode.setGameFlag("DisableKeyboardShortcuts",true)
but with a few differences: you can't pick up or throw items with the mouse, you can't open or close champion windows (but if you open a champion window before disabling controls, you can still manipulate items inside the champion window, switch tabs, train skills, etc.), but you can still attack and swap weapon sets with the mouse. Seems safe enough, provided you always remember to enable the controls again when you're done.
GameMode.getTimeMultiplier(), GameMode.setTimeMultiplier(number)
Remember when I guessed that Grimrock 2 probably has a timescale variable, but I didn't know of a way to change it without memory editing? Well, I wasn't lying, I actually didn't know about GameMode.setTimeMultiplier() at the time. But before you add your Time Slow spell, keep in mind that changing timescale in games generally breaks all manner of things, and that may be the reason this function isn't listed in the scripting reference.
math.atan2(number,number)
http://www.cplusplus.com/reference/cmath/atan2/
math.chromacity(vector)
Doesn't work from the user scripting interface, and to be honest, I have no idea what the hell you'd use chromacity for in the first place.
math.clamp(number num,number min,number max)
Returns the equivalent of math.max(min,math.min(max,num)). Note the order of the parameters to math.min and math.max is relevant if you pass in NaN (this is also how I am able to figure it out).
math.cosh
math.isPow2(number)
Returns true if the number is a non-negative integer power of 2, false otherwise.
math.frexp(number)
Returns the significant and exponent of the number (remember, every number in Lua 5.1 is a binary64 floating point). This is actually extremely useful in certain extremely specific situations.
math.ldexp(number num,number exponent)
Returns num*2^exponent.
math.lerp(number a,number b,number c)
math.lerp(vector a,vector b,number c)
math.lerp(matrix a,matrix b,number c)
Returns the linear interpolation of a and b, with c as the "time" - that is, at 0 it returns a, at 1 it returns b, at 0.5 it returns the average of a and b.
math.log10(number)
Returns the logarithm base 10 of the number. I probably didn't need to say that.
math.luminance(vector)
Treats the vector as a color and returns the luminance.
math.map
I honestly have no clue what this does, other than it seems to want numbers or maybe vectors as arguments.
math.nextPow2(number)
Returns the smallest power of 2 that is greater than or equal to the number. Returns 1 if you pass NaN, in case you needed to know that for some insane reason.
math.noise(number)
Returns a number between -0.5 and 0.5, which is the result of a mysterious mostly-smooth function that seems to have a very long period. Note that this function frequently returns 0. Used widely for flickering lights.
math.pow(number x, number e)
Returns x^e, but is slower than just typing x^e, and doesn't work on vectors...
math.saturation(vector,number)
Used in the asset pack. Treats the vector as a color, and returns a vector representing that color with its saturation multiplied by the number. E.g. math.saturation(vec(1,0.5,0),0.8) returns vec(0.918480, 0.518480, 0.118480, 0.000000), and math.saturation(vec(1,0.5,0),0) returns vec(0.592400, 0.592400, 0.592400, 0.000000). Should you give a saturation value greater than 1, the returned vector can include negative numbers.
math.sign(number)
Returns 1 if number is positive, -1 if number is negative, 0 if number is 0 or NaN.
math.sinh(number)
math.smoothstep(number x, number left, number right)
See https://en.wikipedia.org/wiki/Smoothstep, but note the arguments are in a different order than on that page; x is the first argument instead of the last. Seems like it *should* work on vectors but I always get a stack overflow when I try.
math.sqr(number)
math.sqr(vector)
Returns the square of the argument. Useless for numbers (using the ^ or * operator is many times faster than making a function call) but nice to have for vectors.
math.tanh(number)
MersenneTwister stuff
There's really not much of a reason to mess with any of the undocumented fields on this table, unless you just want to cause a crash.
string.camelCaseToUnderscore(string)
("CamelCase DUCK"):camelCaseToUnderscore() returns "camel_case _d_u_c_k".
string.capitalize(string)
Capitalizes the first letter. ("look out! it's a DUCK"):capitalize() returns "Look out! it's a DUCK".
string.count(string str, string search)
Returns the number of times str contains search.
("duckDUCKduckDUCK"):count("duck") returns 2.
If search is the empty string, enters an infinite loop, so don't do that.
string.gfind
The lua wiki doesn't list this on the string library tutorial page for some reason, but it is a standard Lua library function:
http://www.lua.org/pil/20.1.html
string.split(string str, string delimiter)
Returns a table which is str "split" by delimiter.
("123456DUCK789DUCK0123"):split("DUCK") returns {"123456","789","0123"}.
("cat"):split("DUCK") returns {"cat"}.
If delimiter is the empty string, enters an infinite loop, so don't do that.
string.underscoreToCamelCase(string)
("duck_duck_DUCK_duck"):underscoreToCamelCase() returns "duckDuckDUCKDuck".
table.erase(table)
Assigns nil to all keys in the table, turning it into an empty table.
table.contains(table array,object)
Returns true if any of the values in the array are equal to the object, false otherwise. ONLY WORKS ON ARRAYS (tables with consecutive integer keys). Very useful, but remember that this is an O(n) operation.
table.copy(table)
Returns a shallow copy of the table, including the metatable.
table.deepcopy(table)
Returns a "deep" copy of the table, including the metatable. Copying a GameObject, component, Champion, or pretty much anything else that isn't a simple table will produce a bad object that can't be used for anything useful (won't be added to the map and no methods can be used). However, it works for copying matrices and vectors. But keep in mind that GameObject:getWorldPosition() and GameObject:getWorldRotation() already return copies of the vector and matrix.
table.indexOf(table,object)
If any of the values in the array are equal to the object, returns its index, otherwise returns nil. ONLY WORKS ON ARRAYS (tables with consecutive integer keys). Very useful, but remember that this is an O(n) operation.
table.keys(table)
Returns an array of all the keys in the table.
table.values(table)
Returns an array of all the values in the table. Wanted to use table.contains() on a non-array table? If you aren't concerned about performance, you can use table.contains(table.values(tab),object). Of course, the array returned will be unsorted (except for the part of the table that was already an array, if any), so table.indexOf(table.values(tab),object) is not useful.
Set(array)
This global function is equivalent to
Code: Select all
function set(array)
local rval = {}
for _,v in ipairs(array) do
rval[v]=true
end
return rval
end
Adds two vectors together.
vec.__div(vector,number) or / operator
Divides a vector by a scalar. You cannot divide a vector by another vector, and will get a stack overflow if you try.
vec.__index(table,key) or table indexing operator
vec.__newindex(table,key) or assignment operator
The default vec.__index and vec.__newindex make vec.x equivalent to vec[1], vec.y equivalent to vec[2], etc. The default __newindex will raise an error if you try to assign to an index other than 1, 2, 3, 4, "x", "y", "z", or "w".
vec.__mul(vector,vector or number) or * operator
Multiplies two vectors, or multiplies a vector by a number.
vec.sphericalDirection(number azimuthal,number polar)
Returns a vector pointing in the direction indicated by the passed azimuthal and polar angles (both numbers). Example: vec.sphericalDirection(math.pi/2,math.pi/4) will return vec(0,sqrt(2)/2,sqrt(2)/2).
vec.__sub(vector,vector) or binary - operator
Subtracts one vector from another.
vec.__tostring(vector)
Returns the string representation of the vector (what you get when you use the "print" function to print a vector).
vec.__unm(vector) or unary - operator
Returns the unary minus of the vector.
vec.clone(vector)
Returns a copy of the vector.
vec.cross(vector,vector)
Returns the 3D cross product of two vectors (4th dimension is ignored)
vec.dot(vector,vector)
Returns the dot product of two vectors.
vec.isvec(any)
Returns whether the argument is a vector. Since the global type() function can't differentiate between vectors and tables, this is by far the most convenient way to ensure a value is a vector.
vec.length(vector)
Returns the length of a vector, i.e., sqrt(vector[1]^2+vector[2]^2+vector[3]^2+vector[4]^2).
vec.length3(vector)
Returns the length of the vector ignoring the 4th value, so vec.length3(vec(2,2,2,2)) is the same as vec.length(vec(2,2,2,0)).
FUN FACT: This function is used internally by MonsterWarpComponent's visual effect and absolutely nothing else, so you can change this function to mess with the warp effect without breaking anything else.
vec.lengthSquared(vector)
Like length without the sqrt.
vec.lengthSquared3(vector)
Like length3 without the sqrt.
vec.normalize(vector)
Normalizes a vector.
vec.perpendicular(vector)
Returns a vector that is perpendicular to the argument. Assumes the vector is 3D, so the fourth element is ignored and vec.perpendicular(vec(0,1)) returns vec(0,-0,1)
vec.set(vector a,vector b)
Copies the contents of vector b to vector a.
vec.truncate(vector,number length)
Returns a copy of the vector that is truncated so its length does not exceed length. If the vector's length is already at or below length, the copy is identical to the original vector.