CameraModule API Public Override

I’m making this thread as a response to the not so recent decision by Roblox to make the PlayerScripts camera API private.

Ever since this change developers have been complaining about being unable to access camera API:

And so on…

As a result I wanted to find away around this. So I present to you this module which manages to finagle its way around this module returning an empty table

How to use

This module returns a function that should be called on the CameraModule before PlayerModule has had a chance to run. The easiest place to do this is in the PlayerScriptsLoader, but this may or may not be the right place depending on the rest of your project.

For example:

-- PlayerScriptsLoader
local PlayerModule = script.Parent:WaitForChild("PlayerModule")
local CameraModule = PlayerModule:WaitForChild("CameraModule")
local PatchCameraModule = script.Parent:WaitForChild("PatchCameraModule")


local playerModuleObject = require(PlayerModule)
local cameraModuleObject = playerModuleObject:GetCameras()

-- the api is public!

-- can overwrite the functions
local prevUpdateFunc = cameraModuleObject.Update
function cameraModuleObject.Update(self, ...)
	prevUpdateFunc(self, ...)

Hope you enjoy!

As a complete side note:

I find it annoying that the reasoning provided by Roblox staff has been along the lines of “developers may break something if we leave this code open and accessible”. I don’t say this often, but i really do feel like I speak for all devs when I say: In the future please let us make that decision ourselves. I don’t think a single person asked for this.


Out of curiosity, how do you use this? Is it a simple drop-in modification where you only need to require your module and it’ll automatically find and patch the player module? Looks awesome :slightly_smiling_face:

edit: nvm, it’s on the github! Might be a good idea to include here tho for easier access :stuck_out_tongue:


DANG, now that’s a pro gamer move right there. Someone’s definitely gonna get mad about this.
Maybe they’ll finally break their silence on the matter.

This solution was poorly conceived in the first place. While I have no ill will towards the engineer who made this change, I feel like they seriously misunderstood why people were trying to inject into the module instead of forking it. The whole design goal of the new camera system was to allow people to make changes and extensions to the camera’s functionality without needing to fork the code. This was impossible to do with the previous CameraScript iteration. Completely cutting off access to the camera’s state defeats this purpose entirely.

While I recognize the PlayerModule system is a bit of a volatile mess at this stage and needs to be reworked, completely shutting the door on people with a legitimate use case, regardless of the risks, was a :poop: move. Especially given that they didn’t have an immediate replacement in place or mitigation plan for developers that were hacking into this. They just did it without warning anyone. Why is that acceptable?


This might seem like a dumb question or a useless one but is there a need for the override if we simply use CameraScript and ControlScript ?

That requires you to fork the scripts, meaning you won’t get any updates that Roblox releases to the PlayerModule.

1 Like

Thank you so much for making this !
Although it’s a workaround, so using pcall to be sure, I am happy to be able to use the camera API.

1 Like

I’d like to post this here as it frustrates me a lot.

This is not accurate. The following can be seen at the beginning of the PlayerModule script:

	PlayerModule - This module requires and instantiates the camera and control modules,
	and provides getters for developers to access methods on these singletons without
	having to modify Roblox-supplied scripts.

	2018 PlayerScripts Update - AllYourBlox

That sounds clearly like it was intended to be exposed.

Thank you for this clever workaround, @EgoMoose

1 Like

Just to add my point of view - I tried really hard to gently alter the behavior of the camera controller without outright replacing it.

I spent hours on it before I just went with the EgoMoose injector.
I keep running into things where Roblox makes it 10x easier to make an obby than Unity does.
But then it makes it 10x harder to make something not an obby than Unity does.

1 Like

Echoing some feedback I got on a thing I made that used this… unfortunately, this clever trick seems to be officially dead :frowning:

I was surprised to read this is not working because I have a project that uses the EgoMoose wallstick controller that I played on console, mobile, and PC yesterday that worked fine.

That project broke last year after roblox pushed some VR updates to the camera controller around December. That broke the old wallstick camera injector but it was soon patched.

The CameraModule API Public Override was last updated in March of 2021, so it would not include that patch.

I strongly prefer interfacing with the roblox modules so that future updates (like better VR support, etc) automatically probably work, and maybe I need to issue a patch. In theory

In practice, the a workaround I was using broke once, and the much better workarounds EgoMoose has been able to come up with have broken twice due to roblox pushing updates.

I’m starting to feel it makes more sense to fork the controllers and watch for official updates and merge them in with testing you can deploy on your own timeline instead of having published games fully die when the player controller or camera break suddenly.

/allcaps sad

I ended up going back to the EgoMoose CameraInjector method. The FakeUserSettings workaround no longer works, so I had to take it a step further and setfenv a custom setmetatable function.

@EgoMoose - are you interested in pull requests for these or are you really done updating those projects?

Sure you can submit a PR! I’d also at some point like to make this a wally package.

I’m setting up for the pull request now. Found an issue to tie it to, then rabbit holed hard trying to find some kind of change log for core scripts that is still up to date.

Will fork wallstick first, and hopefully can get it all wrapped up after dinner.