Skip to content

Commit

Permalink
Add modifiers module
Browse files Browse the repository at this point in the history
Runs when the PlayerModule is required thus allowing developers to inject custom code modules into the PlayerModule scripts before anything is initialized.

This helps a fair bit when you want to make lasting changes that can build on top of each other.
  • Loading branch information
EgoMoose committed Mar 29, 2023
1 parent cb00c37 commit ab8eb1c
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local patchModule = script.Parent:WaitForChild("Patch")
local patchModule = script.Parent:FindFirstChild("Patch")
local patch = patchModule and require(patchModule)

local setmetatable = setmetatable
Expand Down
35 changes: 35 additions & 0 deletions cli/PlayerScripts/PlayerModule/Lua/Modifiers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--!strict

local PlayerModule = script.Parent

local module = {}

function module.add(modifier: ModuleScript, priority: number?)
local copy = modifier:Clone()
copy:SetAttribute("Priority", priority)
copy.Parent = script
end

function module.apply()
local children = script:GetChildren() :: {ModuleScript}

table.sort(children, function(a, b)
local pa = a:GetAttribute("Priority") :: number?
local pb = b:GetAttribute("Priority") :: number?

if pa and pb then
return pa < pb
elseif pb then
return false
end

return true
end)

for _, child in children do
local callback = require(child) :: (ModuleScript) -> ()
callback(PlayerModule)
end
end

return module
6 changes: 6 additions & 0 deletions cli/PlayerScripts/PlayerModule/Lua/PlayerModuleHeader.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
local modifiersModule = script:FindFirstChild("Modifiers")
local modifiers = modifiersModule and require(modifiersModule)

if modifiers then
modifiers.apply()
end
4 changes: 1 addition & 3 deletions cli/PlayerScripts/PlayerModule/Lua/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ function module.getCopy(patched: boolean): ModuleScript
return module.get(patched):Clone()
end

function module.replace(patched: boolean): ModuleScript
function module.replace(playerModule: ModuleScript)
local existing = StarterPlayerScripts:FindFirstChild(MODULE_NAME)
if existing then
existing:Destroy()
end

local playerModule = module.getCopy(patched)
playerModule.Parent = StarterPlayerScripts
return playerModule
end

return module
25 changes: 24 additions & 1 deletion cli/PlayerScripts/PlayerModule/Package.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@ def add_package_init(package_path):
os.path.join(package_path, 'init.lua')
)

def patch_player_module(patched_player_module_path):
shutil.copy(
os.path.join(lua_folder, 'Modifiers.lua'),
os.path.join(patched_player_module_path, 'Modifiers.lua')
)

player_module_init_path = os.path.join(
patched_player_module_path,
'init.lua'
)

header = None
with open(os.path.join(lua_folder, 'PlayerModuleHeader.lua'), 'r') as f:
header = f.read()

existing = None
with open(player_module_init_path, 'r') as f:
existing = f.read()

with open(player_module_init_path, 'w') as f:
f.write(header + '\n\n' + existing)

def patch_camera_module(patched_player_module_path):
shutil.copy(
os.path.join(lua_folder, 'Patch.lua'),
Expand All @@ -22,7 +44,7 @@ def patch_camera_module(patched_player_module_path):
)

header = None
with open(os.path.join(lua_folder, 'Header.lua'), 'r') as f:
with open(os.path.join(lua_folder, 'CameraModuleHeader.lua'), 'r') as f:
header = f.read()

existing = None
Expand All @@ -45,6 +67,7 @@ def package(src_path):
shutil.move(tmp_src_path, patched_player_module_path)

add_package_init(src_path)
patch_player_module(patched_player_module_path)
patch_camera_module(patched_player_module_path)

if os.path.exists(tmp_src_path):
Expand Down
34 changes: 32 additions & 2 deletions cli/PlayerScripts/PlayerModule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Package.get(patched: boolean): ModuleScript
Package.getCopy(patched: boolean): ModuleScript

-- replaces the PlayerModule under StarterPlayer.StarterPlayerScripts
-- with a copy of the patched or unpatched version the PlayerModule and returns the copy
Package.replace(patched: boolean): ModuleScript
-- with the provided module script
Package.replace(playerModule: ModuleScript)
```

## Patched CameraModule
Expand All @@ -23,6 +23,7 @@ Package
...
PlayerModulePatched
Patch.lua (new file)
Modifiers.lua (new file)
CameraModule
init.lua (modified)
ControlModule
Expand All @@ -37,6 +38,35 @@ Since this is a open source project it's worth discussing how this module is "pa

### Patch Criteria

#### Modifiers.lua

A submodule is added to the patched `PlayerModule` which provides the ability to write custom code additions/modifications to the `PlayerModule`. The interface of this module looks like this:

```Lua
-- adds custom modifier module script to be run at a certain priority level
-- if no priority is specified then the code will be run at the end in no particular order
Modifiers.add(modifier: ModuleScript, priority: number?)
```

The modifier modules themselves are quite straightforward. They should return a function that accepts one argument: reference to the `PlayerModule` instance. For example a modifier might look like this:

```Lua
-- some module in the game that handles player control
local controlBindings = require(...)

return function (PlayerModule: ModuleScript)
local controlObject = require(PlayerModule.ControlModule)

controlBindings.setEnableCallback(function(enabled)
if enabled then
controlObject:Enable()
else
controlObject:Disable()
end
end)
end
```

#### Only header additions

Your first thought if asked to make the CameraModule API public might be to write a regex replace or modify lines in the existing source string so that the module doesn't return an empty table.
Expand Down

0 comments on commit ab8eb1c

Please sign in to comment.