@quenty/fakeskybox 11.15.0 → 11.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,258 @@
1
+ --!strict
2
+ --[=[
3
+ @class SkyboxRenderPart
4
+ ]=]
5
+
6
+ local require = require(script.Parent.loader).load(script)
7
+
8
+ local BaseObject = require("BaseObject")
9
+ local Blend = require("Blend")
10
+ local ColorSequenceUtils = require("ColorSequenceUtils")
11
+ local FakeSkyboxRenderMethod = require("FakeSkyboxRenderMethod")
12
+ local Rx = require("Rx")
13
+ local ValueObject = require("ValueObject")
14
+
15
+ local SkyboxRenderPart = setmetatable({}, BaseObject)
16
+ SkyboxRenderPart.__index = SkyboxRenderPart
17
+ SkyboxRenderPart.ClassName = "SkyboxRenderPart"
18
+
19
+ export type SkyboxRenderPart =
20
+ typeof(setmetatable(
21
+ {} :: {
22
+ Gui: Part,
23
+ _partRef: ValueObject.ValueObject<Part>,
24
+ _size: ValueObject.ValueObject<Vector3>,
25
+ _transparency: ValueObject.ValueObject<number>,
26
+ _zOffset: ValueObject.ValueObject<number>,
27
+ _cframe: ValueObject.ValueObject<CFrame>,
28
+ _image: ValueObject.ValueObject<string>,
29
+ _canvasSize: ValueObject.ValueObject<Vector2>,
30
+ _brightness: ValueObject.ValueObject<number>,
31
+ _imageColor3: ValueObject.ValueObject<Color3>,
32
+ _imageGradientSequence: ValueObject.ValueObject<ColorSequence?>,
33
+ _renderMethod: ValueObject.ValueObject<FakeSkyboxRenderMethod.FakeSkyboxRenderMethod>,
34
+ },
35
+ {} :: typeof({ __index = SkyboxRenderPart })
36
+ ))
37
+ & BaseObject.BaseObject
38
+
39
+ function SkyboxRenderPart.new(): SkyboxRenderPart
40
+ local self: SkyboxRenderPart = setmetatable(BaseObject.new() :: any, SkyboxRenderPart)
41
+
42
+ self._partRef = self._maid:Add(ValueObject.new(nil))
43
+ self._size = self._maid:Add(ValueObject.new(Vector3.new(1, 1, 1), "Vector3"))
44
+ self._zOffset = self._maid:Add(ValueObject.new(0, "number"))
45
+ self._transparency = self._maid:Add(ValueObject.new(1, "number"))
46
+ self._cframe = self._maid:Add(ValueObject.new(CFrame.identity, "CFrame"))
47
+ self._image = self._maid:Add(ValueObject.new("", "string"))
48
+ self._imageColor3 = self._maid:Add(ValueObject.new(Color3.new(1, 1, 1), "Color3"))
49
+ self._imageGradientSequence = self._maid:Add(ValueObject.new(nil))
50
+ self._brightness = self._maid:Add(ValueObject.new(1, "number"))
51
+ self._canvasSize = self._maid:Add(ValueObject.new(Vector2.new(512, 512), "Vector2"))
52
+ self._renderMethod =
53
+ self._maid:Add(ValueObject.new(FakeSkyboxRenderMethod.SURFACEGUI :: any, FakeSkyboxRenderMethod:GetInterface()))
54
+
55
+ self._maid:GiveTask(self:_render():Subscribe(function(gui)
56
+ self.Gui = gui
57
+ end))
58
+
59
+ return self
60
+ end
61
+
62
+ function SkyboxRenderPart.SetCFrame(self: SkyboxRenderPart, cframe: ValueObject.Mountable<CFrame>): () -> ()
63
+ return self._cframe:Mount(cframe)
64
+ end
65
+
66
+ function SkyboxRenderPart.SetRenderMethod(
67
+ self: SkyboxRenderPart,
68
+ renderMethod: ValueObject.Mountable<FakeSkyboxRenderMethod.FakeSkyboxRenderMethod>
69
+ ): () -> ()
70
+ return self._renderMethod:Mount(renderMethod)
71
+ end
72
+
73
+ function SkyboxRenderPart.SetCanvasSize(self: SkyboxRenderPart, canvasSize: ValueObject.Mountable<Vector2>): () -> ()
74
+ return self._canvasSize:Mount(canvasSize)
75
+ end
76
+
77
+ function SkyboxRenderPart.SetBrightness(self: SkyboxRenderPart, brightness: ValueObject.Mountable<number>): () -> ()
78
+ return self._brightness:Mount(brightness)
79
+ end
80
+
81
+ function SkyboxRenderPart.SetImageColor3(self: SkyboxRenderPart, imageColor3: ValueObject.Mountable<Color3>): () -> ()
82
+ return self._imageColor3:Mount(imageColor3)
83
+ end
84
+
85
+ function SkyboxRenderPart.SetImageGradientSequence(
86
+ self: SkyboxRenderPart,
87
+ imageGradientSequence: ValueObject.Mountable<ColorSequence?>
88
+ ): () -> ()
89
+ return self._imageGradientSequence:Mount(imageGradientSequence)
90
+ end
91
+
92
+ function SkyboxRenderPart.SetSize(self: SkyboxRenderPart, size: ValueObject.Mountable<Vector3>): () -> ()
93
+ return self._size:Mount(size)
94
+ end
95
+
96
+ function SkyboxRenderPart.SetImage(self: SkyboxRenderPart, image: ValueObject.Mountable<string>): () -> ()
97
+ return self._image:Mount(image)
98
+ end
99
+
100
+ function SkyboxRenderPart.SetTransparency(self: SkyboxRenderPart, transparency: ValueObject.Mountable<number>): () -> ()
101
+ return self._transparency:Mount(transparency)
102
+ end
103
+
104
+ function SkyboxRenderPart.SetZOffset(self: SkyboxRenderPart, zOffset: ValueObject.Mountable<number>): () -> ()
105
+ return self._zOffset:Mount(zOffset)
106
+ end
107
+
108
+ function SkyboxRenderPart._render(self: SkyboxRenderPart): any
109
+ local observeSingleSequenceColor = self._imageGradientSequence:Observe():Pipe({
110
+ Rx.map(function(imageGradientSequence): Color3?
111
+ if imageGradientSequence == nil then
112
+ return nil
113
+ end
114
+
115
+ return ColorSequenceUtils.getSingleColorInSequence(imageGradientSequence)
116
+ end) :: any,
117
+ Rx.cache() :: any,
118
+ })
119
+
120
+ local observeTopColorOfGradient = self._imageGradientSequence:Observe():Pipe({
121
+ Rx.map(function(imageGradientSequence): Color3?
122
+ if imageGradientSequence == nil then
123
+ return nil
124
+ end
125
+
126
+ return ColorSequenceUtils.getColor(imageGradientSequence, 1)
127
+ end) :: any,
128
+ Rx.cache() :: any,
129
+ })
130
+
131
+ local observeDecalColor3 = Blend.Computed(
132
+ observeSingleSequenceColor,
133
+ observeTopColorOfGradient,
134
+ self._imageColor3:Observe(),
135
+ self._brightness:Observe(),
136
+ function(
137
+ singleSequenceColor: Color3?,
138
+ topColorOfGradient: Color3?,
139
+ imageColor3: Color3,
140
+ brightness: number
141
+ ): Color3
142
+ -- We blend with the "top" color since usually you look up, not down
143
+ local blendWithColor
144
+ if singleSequenceColor ~= nil then
145
+ blendWithColor = singleSequenceColor
146
+ elseif topColorOfGradient ~= nil then
147
+ blendWithColor = topColorOfGradient
148
+ else
149
+ blendWithColor = Color3.new(1, 1, 1)
150
+ end
151
+
152
+ -- We also compensate for brightness here since decals don't respond to it like surface guis do
153
+ return Color3.new(
154
+ imageColor3.R * blendWithColor.R * brightness,
155
+ imageColor3.G * blendWithColor.G * brightness,
156
+ imageColor3.B * blendWithColor.B * brightness
157
+ )
158
+ end
159
+ )
160
+
161
+ local observeImageColor3 = Blend.Shared(
162
+ Blend.Computed(
163
+ observeSingleSequenceColor,
164
+ self._imageColor3:Observe(),
165
+ function(singleSequenceColor: Color3?, imageColor3: Color3): Color3
166
+ if singleSequenceColor == nil then
167
+ -- Gradient will tint
168
+ return imageColor3
169
+ end
170
+
171
+ return Color3.new(
172
+ imageColor3.R * singleSequenceColor.R,
173
+ imageColor3.G * singleSequenceColor.G,
174
+ imageColor3.B * singleSequenceColor.B
175
+ )
176
+ end
177
+ )
178
+ )
179
+
180
+ return Blend.New "Part" {
181
+ Name = "SkyboxPart",
182
+ Anchored = true,
183
+ Transparency = 1,
184
+ Color = observeImageColor3,
185
+ CanCollide = false,
186
+ CastShadow = false,
187
+ CanQuery = false,
188
+ CanTouch = false,
189
+ AudioCanCollide = false,
190
+ Material = Enum.Material.Fabric, -- Reduces specularity, but we should do something more custom in general
191
+ Size = self._size:Observe(),
192
+ CFrame = self._cframe:Observe(),
193
+
194
+ [Blend.Instance] = self._partRef,
195
+
196
+ Blend.New "Decal" {
197
+ Name = "SkyboxDecal",
198
+ Face = Enum.NormalId.Front,
199
+ ColorMap = self._image:Observe(),
200
+ Color3 = observeDecalColor3,
201
+ Transparency = Blend.Computed(
202
+ self._renderMethod,
203
+ self._transparency:Observe(),
204
+ function(renderMethod, transparency)
205
+ if renderMethod == FakeSkyboxRenderMethod.DECAL then
206
+ return transparency
207
+ else
208
+ return 1
209
+ end
210
+ end
211
+ ),
212
+ ZIndex = self._zOffset:Observe(),
213
+ },
214
+
215
+ Blend.New "SurfaceGui" {
216
+ Adornee = self._partRef,
217
+ AutoLocalize = false,
218
+ SizingMode = Enum.SurfaceGuiSizingMode.FixedSize,
219
+ Active = false,
220
+ CanvasSize = self._canvasSize:Observe(),
221
+ LightInfluence = 0,
222
+ Brightness = self._brightness:Observe(),
223
+ Face = Enum.NormalId.Front,
224
+ ZOffset = self._zOffset:Observe(),
225
+ Enabled = Blend.Computed(self._renderMethod, function(renderMethod)
226
+ return renderMethod == FakeSkyboxRenderMethod.SURFACEGUI
227
+ end),
228
+
229
+ Blend.New "ImageLabel" {
230
+ Name = "SkyboxImage",
231
+ AnchorPoint = Vector2.new(0.5, 0.5),
232
+ Position = UDim2.fromScale(0.5, 0.5),
233
+ Size = UDim2.fromScale(1, 1),
234
+ ImageTransparency = self._transparency:Observe(),
235
+ Image = self._image:Observe(),
236
+ ImageColor3 = observeImageColor3,
237
+ BackgroundColor3 = Color3.new(0, 0, 0),
238
+ BackgroundTransparency = 1,
239
+ BorderSizePixel = 0,
240
+
241
+ Blend.New "UIGradient" {
242
+ Name = "SkyboxGradient",
243
+ Enabled = Blend.Computed(observeSingleSequenceColor, function(color)
244
+ return color == nil
245
+ end),
246
+ Color = self._imageGradientSequence:Observe():Pipe({
247
+ Rx.where(function(imageGradientSequence)
248
+ return imageGradientSequence ~= nil
249
+ end) :: any,
250
+ }) :: any,
251
+ Rotation = -90,
252
+ },
253
+ },
254
+ },
255
+ }
256
+ end
257
+
258
+ return SkyboxRenderPart
@@ -0,0 +1,135 @@
1
+ --!strict
2
+ --[=[
3
+ @class SkyboxSide
4
+ ]=]
5
+
6
+ local require = require(script.Parent.loader).load(script)
7
+
8
+ local BaseObject = require("BaseObject")
9
+ local Blend = require("Blend")
10
+ local ColorSequenceUtils = require("ColorSequenceUtils")
11
+ local FakeSkyboxRenderMethod = require("FakeSkyboxRenderMethod")
12
+ local Observable = require("Observable")
13
+ local SkyboxRenderPart = require("SkyboxRenderPart")
14
+ local ValueObject = require("ValueObject")
15
+
16
+ local SkyboxSide = setmetatable({}, BaseObject)
17
+ SkyboxSide.__index = SkyboxSide
18
+ SkyboxSide.ClassName = "SkyboxSide"
19
+
20
+ local RENDER_PART_DEPTH = 1
21
+
22
+ export type SkyboxSide =
23
+ typeof(setmetatable(
24
+ {} :: {
25
+ Gui: Part,
26
+ _normal: Enum.NormalId,
27
+ _renderPart: SkyboxRenderPart.SkyboxRenderPart,
28
+ _skyboxWidth: ValueObject.ValueObject<number>,
29
+ _skyboxCFrame: ValueObject.ValueObject<CFrame>,
30
+ _skyboxGradient: ValueObject.ValueObject<ColorSequence>,
31
+ },
32
+ {} :: typeof({ __index = SkyboxSide })
33
+ ))
34
+ & BaseObject.BaseObject
35
+
36
+ function SkyboxSide.new(normal: Enum.NormalId): SkyboxSide
37
+ assert(normal, "Bad normal")
38
+
39
+ local self: SkyboxSide = setmetatable(BaseObject.new() :: any, SkyboxSide)
40
+
41
+ self._normal = normal
42
+ self._skyboxWidth = self._maid:Add(ValueObject.new(1024, "number"))
43
+ self._skyboxCFrame = self._maid:Add(ValueObject.new(CFrame.identity, "CFrame"))
44
+ self._skyboxGradient = self._maid:Add(ValueObject.new(ColorSequence.new(Color3.new(1, 1, 1)), "ColorSequence"))
45
+
46
+ self._renderPart = self._maid:Add(SkyboxRenderPart.new())
47
+ self._renderPart:SetCFrame(
48
+ Blend.Computed(self._skyboxWidth, self._skyboxCFrame, function(skyboxWidth: number, skyboxCFrame: CFrame)
49
+ local direction = Vector3.FromNormalId(self._normal)
50
+ local offset = direction * RENDER_PART_DEPTH / 2
51
+
52
+ local relativeOffset = CFrame.new(direction * (skyboxWidth / 2) + offset)
53
+ * CFrame.new(Vector3.zero, -direction)
54
+
55
+ if self._normal == Enum.NormalId.Bottom then
56
+ -- Hack
57
+ relativeOffset = relativeOffset * CFrame.Angles(0, 0, math.pi)
58
+ end
59
+
60
+ return skyboxCFrame * relativeOffset
61
+ end)
62
+ )
63
+ self._renderPart:SetSize(Blend.Computed(self._skyboxWidth, function(skyboxWidth: number)
64
+ return Vector3.new(skyboxWidth, skyboxWidth, RENDER_PART_DEPTH)
65
+ end))
66
+ self._renderPart:SetImageGradientSequence(self:_observeImageGradientSequence())
67
+
68
+ self.Gui = self._renderPart.Gui
69
+ self.Gui.Name = self._normal.Name .. "SkyboxPart"
70
+
71
+ return self
72
+ end
73
+
74
+ function SkyboxSide.SetRenderMethod(
75
+ self: SkyboxSide,
76
+ renderMethod: ValueObject.Mountable<FakeSkyboxRenderMethod.FakeSkyboxRenderMethod>
77
+ ): () -> ()
78
+ return self._renderPart:SetRenderMethod(renderMethod)
79
+ end
80
+
81
+ function SkyboxSide.SetZOffset(self: SkyboxSide, zOffset: ValueObject.Mountable<number>): () -> ()
82
+ return self._renderPart:SetZOffset(zOffset)
83
+ end
84
+
85
+ function SkyboxSide.SetSkyboxGradient(self: SkyboxSide, skyboxGradient: ValueObject.Mountable<ColorSequence>): () -> ()
86
+ return self._skyboxGradient:Mount(skyboxGradient)
87
+ end
88
+
89
+ function SkyboxSide._observeImageGradientSequence(self): Observable.Observable<ColorSequence?>
90
+ return Blend.Computed(
91
+ self._renderMode,
92
+ self._skyboxGradient,
93
+ self._normal,
94
+ function(
95
+ renderMode: FakeSkyboxRenderMethod.FakeSkyboxRenderMethod,
96
+ skyboxGradient: ColorSequence,
97
+ normal: Enum.NormalId
98
+ ): ColorSequence
99
+ if renderMode == FakeSkyboxRenderMethod.DECAL then
100
+ -- Decal mode doesn't support gradient, so we just use the lowest color for tinting
101
+ return ColorSequence.new(ColorSequenceUtils.getColor(skyboxGradient, 0))
102
+ end
103
+
104
+ if normal == Enum.NormalId.Top then
105
+ return ColorSequence.new(ColorSequenceUtils.getColor(skyboxGradient, 1))
106
+ elseif normal == Enum.NormalId.Bottom then
107
+ return ColorSequence.new(ColorSequenceUtils.getColor(skyboxGradient, 0))
108
+ else
109
+ return skyboxGradient
110
+ end
111
+ end
112
+ )
113
+ end
114
+
115
+ function SkyboxSide.SetBrightness(self: SkyboxSide, brightness: ValueObject.Mountable<number>): () -> ()
116
+ return self._renderPart:SetBrightness(brightness)
117
+ end
118
+
119
+ function SkyboxSide.SetPartSize(self: SkyboxSide, skyboxWidth: ValueObject.Mountable<number>): () -> ()
120
+ return self._skyboxWidth:Mount(skyboxWidth)
121
+ end
122
+
123
+ function SkyboxSide.SetImage(self: SkyboxSide, image: ValueObject.Mountable<string>): () -> ()
124
+ return self._renderPart:SetImage(image)
125
+ end
126
+
127
+ function SkyboxSide.SetTransparency(self: SkyboxSide, transparency: ValueObject.Mountable<number>): () -> ()
128
+ return self._renderPart:SetTransparency(transparency)
129
+ end
130
+
131
+ function SkyboxSide.SetSkyboxCFrame(self: SkyboxSide, skyboxCFrame: ValueObject.Mountable<CFrame>): () -> ()
132
+ return self._skyboxCFrame:Mount(skyboxCFrame)
133
+ end
134
+
135
+ return SkyboxSide
@@ -0,0 +1,17 @@
1
+ --[=[
2
+ @class FakeSkyboxService
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local ServiceBag = require("ServiceBag")
8
+
9
+ local FakeSkyboxService = {}
10
+ FakeSkyboxService.ServiceName = "FakeSkyboxService"
11
+
12
+ function FakeSkyboxService:Init(serviceBag: ServiceBag.ServiceBag)
13
+ assert(not self._serviceBag, "Already initialized")
14
+ self._serviceBag = assert(serviceBag, "No serviceBag")
15
+ end
16
+
17
+ return FakeSkyboxService
@@ -0,0 +1,3 @@
1
+ return {
2
+ testMatch = { "**/*.spec" },
3
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "FakeSkyboxTest",
3
+ "globIgnorePaths": [
4
+ "**/.package-lock.json",
5
+ "**/.pnpm",
6
+ "**/.pnpm-workspace-state-v1.json",
7
+ "**/.modules.yaml",
8
+ "**/.ignored",
9
+ "**/.ignored_*"
10
+ ],
11
+ "tree": {
12
+ "$className": "DataModel",
13
+ "ServerScriptService": {
14
+ "$properties": {
15
+ "LoadStringEnabled": true
16
+ },
17
+ "fakeskybox": {
18
+ "$path": ".."
19
+ },
20
+ "Script": {
21
+ "$path": "scripts/Server"
22
+ }
23
+ },
24
+ "StarterPlayer": {
25
+ "StarterPlayerScripts": {
26
+ "Main": {
27
+ "$path": "scripts/Client"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,235 @@
1
+ --[[
2
+ @class ClientMain
3
+ ]]
4
+ local loader = game:GetService("ReplicatedStorage"):WaitForChild("fakeskybox"):WaitForChild("loader")
5
+ local require = require(loader).bootstrapGame(loader.Parent)
6
+
7
+ local serviceBag = require("ServiceBag").new()
8
+ serviceBag:GetService(require("FakeSkyboxServiceClient"))
9
+ serviceBag:Init()
10
+ serviceBag:Start()
11
+
12
+ local Lighting = game:GetService("Lighting")
13
+ local Players = game:GetService("Players")
14
+ local UserInputService = game:GetService("UserInputService")
15
+
16
+ local Blend = require("Blend")
17
+ local FakeSkybox = require("FakeSkybox")
18
+ local FakeSkyboxRenderMethod = require("FakeSkyboxRenderMethod")
19
+ local Observable = require("Observable")
20
+ local Rx = require("Rx")
21
+ local RxInstanceUtils = require("RxInstanceUtils")
22
+ local RxStateStackUtils = require("RxStateStackUtils")
23
+
24
+ local function observeSkyboxProperty(property: string): Observable.Observable<any>
25
+ return RxInstanceUtils.observeChildrenOfClassBrio(Lighting, "Sky")
26
+ :Pipe({
27
+ RxStateStackUtils.topOfStack(nil) :: any,
28
+ })
29
+ :Pipe({
30
+ Rx.switchMap(function(sky)
31
+ if not sky then
32
+ return Rx.EMPTY
33
+ end
34
+
35
+ return RxInstanceUtils.observeProperty(sky, property)
36
+ end),
37
+ })
38
+ end
39
+
40
+ local skybox = FakeSkybox.new()
41
+ skybox.Gui.Parent = workspace.CurrentCamera
42
+ skybox:SetSpeed(10)
43
+ skybox:Show(true)
44
+ skybox:SetRenderMethod(FakeSkyboxRenderMethod.DECAL)
45
+
46
+ type Props = {
47
+ Text: string,
48
+ OnActivated: () -> (),
49
+ TextSize: number?,
50
+ }
51
+ local function button(props: Props)
52
+ return Blend.New "TextButton" {
53
+ Text = props.Text,
54
+ AutomaticSize = Enum.AutomaticSize.XY,
55
+ AutoButtonColor = true,
56
+ TextColor3 = Color3.new(1, 1, 1),
57
+ BackgroundColor3 = Color3.new(0, 0, 0),
58
+ Font = Enum.Font.SourceSansBold,
59
+ TextSize = props.TextSize or 18,
60
+
61
+ [Blend.OnEvent "Activated"] = props.OnActivated,
62
+
63
+ Blend.New "UIPadding" {
64
+ PaddingLeft = UDim.new(0, 8),
65
+ PaddingRight = UDim.new(0, 8),
66
+ PaddingTop = UDim.new(0, 8),
67
+ PaddingBottom = UDim.new(0, 8),
68
+ },
69
+
70
+ Blend.New "UICorner" {
71
+ CornerRadius = UDim.new(0, 4),
72
+ Name = "UICorner",
73
+ },
74
+ }
75
+ end
76
+
77
+ local sunsetSky = Blend.State(nil)
78
+ local islandSky = Blend.State(nil)
79
+
80
+ Blend.mount(Players.LocalPlayer:WaitForChild("PlayerGui"), {
81
+ Blend.New "ScreenGui" {
82
+ Name = "TestSkyboxGui",
83
+ ResetOnSpawn = false,
84
+ IgnoreGuiInset = true,
85
+
86
+ Blend.New "Frame" {
87
+ AutomaticSize = Enum.AutomaticSize.XY,
88
+ Position = UDim2.fromScale(0.5, 0.8),
89
+ AnchorPoint = Vector2.new(0.5, 0.5),
90
+ BackgroundTransparency = 1,
91
+
92
+ Blend.New "UIListLayout" {
93
+ FillDirection = Enum.FillDirection.Vertical,
94
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
95
+ VerticalAlignment = Enum.VerticalAlignment.Center,
96
+ Padding = UDim.new(0, 8),
97
+ },
98
+
99
+ button {
100
+ Text = Blend.Computed(skybox:ObserveVisible(), function(visible)
101
+ return `Toggle [E] {visible and "Fake Skybox Enabled" or ""}`
102
+ end),
103
+ OnActivated = function()
104
+ skybox:SetVisible(not skybox:IsVisible())
105
+ end,
106
+ TextSize = 24,
107
+ },
108
+
109
+ Blend.New "Frame" {
110
+ AutomaticSize = Enum.AutomaticSize.XY,
111
+ BackgroundTransparency = 1,
112
+
113
+ Blend.New "UIListLayout" {
114
+ FillDirection = Enum.FillDirection.Horizontal,
115
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
116
+ VerticalAlignment = Enum.VerticalAlignment.Center,
117
+ Padding = UDim.new(0, 4),
118
+ },
119
+
120
+ button {
121
+ Text = "Random time of day",
122
+ OnActivated = function()
123
+ Lighting.ClockTime = math.random() * 24
124
+ end,
125
+ },
126
+
127
+ button {
128
+ Text = "3 AM",
129
+ OnActivated = function()
130
+ Lighting.ClockTime = 3
131
+ end,
132
+ },
133
+
134
+ button {
135
+ Text = "Afternoon",
136
+ OnActivated = function()
137
+ Lighting.ClockTime = 14.5
138
+ end,
139
+ },
140
+
141
+ button {
142
+ Text = "Sunset",
143
+ OnActivated = function()
144
+ Lighting.ClockTime = 17.9
145
+ end,
146
+ },
147
+
148
+ button {
149
+ Text = "Atmosphere off",
150
+ OnActivated = function()
151
+ Lighting.Atmosphere.Density = 0
152
+ end,
153
+ },
154
+
155
+ button {
156
+ Text = "Atmosphere on",
157
+ OnActivated = function()
158
+ Lighting.Atmosphere.Density = 0.3
159
+ end,
160
+ },
161
+ },
162
+
163
+ Blend.New "Frame" {
164
+ AutomaticSize = Enum.AutomaticSize.XY,
165
+ BackgroundTransparency = 1,
166
+
167
+ Blend.New "UIListLayout" {
168
+ FillDirection = Enum.FillDirection.Horizontal,
169
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
170
+ VerticalAlignment = Enum.VerticalAlignment.Center,
171
+ Padding = UDim.new(0, 4),
172
+ },
173
+
174
+ button {
175
+ Text = "Fake Empty baseplate",
176
+ OnActivated = function()
177
+ skybox:SetSky(nil)
178
+ end,
179
+ },
180
+
181
+ button {
182
+ Text = "Fake Sunset",
183
+ OnActivated = function()
184
+ skybox:SetSky(sunsetSky.Value)
185
+ end,
186
+ },
187
+
188
+ button {
189
+ Text = "Fake Island",
190
+ OnActivated = function()
191
+ skybox:SetSky(islandSky.Value)
192
+ end,
193
+ },
194
+ },
195
+
196
+ Blend.New "Sky" {
197
+ SkyboxBk = "rbxassetid://653719502",
198
+ SkyboxDn = "rbxassetid://653718790",
199
+ SkyboxFt = "rbxassetid://653719067",
200
+ SkyboxLf = "rbxassetid://653719190",
201
+ SkyboxRt = "rbxassetid://653718931",
202
+ SkyboxUp = "rbxassetid://653719321",
203
+ SunTextureId = observeSkyboxProperty("SunTextureId"),
204
+ MoonTextureId = observeSkyboxProperty("MoonTextureId"),
205
+ SunAngularSize = observeSkyboxProperty("SunAngularSize"),
206
+ MoonAngularSize = observeSkyboxProperty("MoonAngularSize"),
207
+ SkyboxOrientation = observeSkyboxProperty("SkyboxOrientation"),
208
+ CelestialBodiesShown = observeSkyboxProperty("CelestialBodiesShown"),
209
+ StarCount = observeSkyboxProperty("StarCount"),
210
+ [Blend.Instance] = sunsetSky,
211
+ },
212
+
213
+ Blend.New "Sky" {
214
+ Name = "Island Sky",
215
+ CelestialBodiesShown = false,
216
+ SkyboxBk = "http://www.roblox.com/asset/?id=319343577",
217
+ SkyboxDn = "http://www.roblox.com/asset/?id=319343653",
218
+ SkyboxFt = "http://www.roblox.com/asset/?id=319343666",
219
+ SkyboxLf = "http://www.roblox.com/asset/?id=319343686",
220
+ SkyboxRt = "http://www.roblox.com/asset/?id=319343631",
221
+ SkyboxUp = "http://www.roblox.com/asset/?id=319343614",
222
+ StarCount = 500,
223
+ [Blend.Instance] = islandSky,
224
+ },
225
+ },
226
+ },
227
+ })
228
+
229
+ skybox:SetSky(sunsetSky.Value)
230
+
231
+ UserInputService.InputBegan:Connect(function(input)
232
+ if input.KeyCode == Enum.KeyCode.E then
233
+ skybox:SetVisible(not skybox:IsVisible())
234
+ end
235
+ end)
@@ -0,0 +1,18 @@
1
+ --[[
2
+ @class ServerMain
3
+ ]]
4
+ local ServerScriptService = game:GetService("ServerScriptService")
5
+
6
+ local root = ServerScriptService.fakeskybox
7
+ local loader = root:FindFirstChild("LoaderUtils", true).Parent
8
+ local require = require(loader).bootstrapGame(root)
9
+
10
+ local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
11
+ if NevermoreTestRunnerUtils.runTestsIfNeededAsync(root) then
12
+ return
13
+ end
14
+
15
+ local serviceBag = require("ServiceBag").new()
16
+ serviceBag:GetService(require("FakeSkyboxService"))
17
+ serviceBag:Init()
18
+ serviceBag:Start()