- INTRODUCTION -
I'm quite sure you guys already know this limitation in Bully. But.. if you haven't notice it yet, let me explain it to you briefly.
So.. Bully has some kind of limitation on their engine i suppose, which is not allowing you to put any of compiled script beyond 112kb. It will crash the game upon starts if doing so. We used to solve this problem by
code-splitting, we certainly use
ImportScript function in the main script in order to retrieve the shards of code from another script. That's what we keep doing over the years in order to avoid 112kb limit.
Well, actually.. there is another way better than
ImportScript.
You can even load 1.8mb of compiled script (tested by me so far) without splitting it.
- DISCLAIMER -
Based on the introduction above, i have no single intention to call
code-splitting in
negative connotation.
I mean, i have no problem with
code-spiltting anyway, it's a good thing, easy to understand, and clear about their scopes. I often do that to my mods because i like well-structured scripts.. (maybe). Even most people often do that too, also in some cases, they MUST do it for whatever reasons they have.
- LOADFILE -
I assume you already heard about
loadfile, yes.. this function is available in Lua modified-standard library 5.0.2 used by Bully. Its job is pretty much similar to
ImportScript as they do call upon another script into the main one. But.. there are few difference between them, one of the most noticeable is the
ImportScript call scripts from Scripts.img and
loadfile call scripts from directory.
* if you have no idea what directory is, you may read this wikipedia page before continuing *1) DEFAULT PATHBased on Lua 5.0.2 documentation,
loadfile function requires a specific file path as its main argument.
But as far as observed it myself, some versions of Bully may have different default directory.
I only know the default directory of
loadfile on SE (PC) and AE (Android) since i don't play any other version except both.
PC default directory =
where Bully.exe is located Android default directory =
where storage folder is located (3 folders before
"../Android/")
However, i would STRONGLY advise you to place your script in Scripts folder as they're related.
PC =
"../Bully - Scholarship Edition/Scripts" (Bully folder > Scripts folder)
Android =
"../Android/data/com.rockstargames.bully/files/BullyOrig/Scripts" * if BullyOrig or Scripts folder doesn't exist, create new one *2) FILE REQUIREMENTIn the modified version of Lua standard library we have,
loadfile function cannot read anything but compiled Lua 5.0.2.
That means, it cannot read Lua source code directly or any Lua 5.1 (and beyond) compiled script.
Otherwise, it will show you an error message. --> "
parser not loaded"
If your file is already compiled by LuaC, you can rename it and its extension to anything you want.
The extension of file does not really necessary as the game also recognize it, as long as it's compiled by LuaC.
3) OTHERloadfile mechanism is quite similar to
dofile, make sure you don't confuse with both.
I would not explain
dofile here, it's quite same already.
- EXCEEDING 112KB TUTORIAL -
1. Create new Lua script and name it RESOURCE.lua
2. Fill the RESOURCE.lua with some
gigantic-size contents, you can copy this for example:
-- this is all .NIF files available in World.img
-- EDIT: Table is too long to be here, i uploaded it on the link below
https://pastebin.com/jXUUYbcG
3. Compile RESOURCE.lua with LuaC and name it to RESOURCE.lur
* you can clearly see RESOURCE.lur size is bigger than 112kb *4. Create new Lua script and name it STimeCycle.lua
5. Fill the STimeCycle.lua with this hybrid script:
function main()
while SystemIsReady() or AreaIsLoading() do
Wait(0)
end
local PC = type(_G.ClassMusicSetPlayers) == "function" and true or false
local DIR = PC and "Scripts" or "storage/emulated/0/Android/data/com.rockstargames.bully/files/BullyOrig/Scripts"
local FILE_NAME = "RESOURCE.lur" -- replace this with your file name!
local FILE, ERROR = loadfile(DIR.."/"..FILE_NAME)
if FILE then
FILE()
if not PC then
Wait(1500)
end
local OPTION, X, Y, Z = 1
while true do
Wait(0)
X, Y, Z = PlayerGetPosXYZ()
OPTION = IsButtonBeingPressed(PC and 0 or 8, 0) and (OPTION - 1 < 1 and table.getn(TABLE) or OPTION - 1) or (IsButtonBeingPressed(PC and 1 or 11, 0) and (OPTION + 1 > table.getn(TABLE) and 1 or OPTION + 1) or OPTION)
if IsButtonBeingPressed(PC and 3 or 6, 0) then
CreatePersistentEntity(TABLE[OPTION].Name, X + 2, Y + 2, Z, 0, AreaGetVisible())
end
if not PC then
if ItemGetCurrentNum(420) then
GiveWeaponToPlayer(420, false)
end
PlayerLockButtonInputsExcept(true, 2, 3, 4, 5, 7, 9, 14, 15, 16, 17, 18, 19)
end
_G[PC and "TextPrintString" or "MinigameSetAnnouncement"]((PC and "- EXCEED 112KB DEMO -\n\n" or "")..""..OPTION..") "..TABLE[OPTION].Name, PC and 0 or true, PC and 1 or nil)
end
else
while true do
Wait(0)
TextPrintString(tostring(ERROR), 0, 2)
end
end
end
6. Compile STimeCycle.lua with LuaC and name it to STimeCycle.lur
7. Copy RESOURCE.lur and paste it into your Scripts folder
* SE (PC) = "../Bully - Scholarship Edition/Scripts" * AE (Android) = "../Android/data/com.rockstargames.bully/files/BullyOrig/Scripts"8. Insert STimeCycle.lur into your Scripts.img and don't forget to rebuild
9. Go play Bully and see the results
- CLOSING STATEMENT -
This is my first tutorial in Bully-Board, i hope i'll be able to share some more experiences soon.
Make sure you read all the explanations carefully to avoid any confusion.
External links:
-
Compilation, Execution, and Errors via lua.org
-
Loads a Lua file and parses it via gammon.com
Check out my other tutorials:
-
Lua Tutorial: Non-STimeCycle Freeroam Mods-
Lua Tutorial: Check If a File Exists in Directory