Immersive Environments V2 - Advanced 'Package'-Based Audio and Lighting Control

Immersive Environments V2 - Packages

Download

GitHub Repository
Roblox Library Model
Example Place

Key New Features

  • Packages support
  • Expanded control and flexibility
  • Better internal handling for regions
  • Minimalist API
  • Easier to fork and modify (internally more coherent)
  • CullingService compatibility

What are Packages?

Packages are a collection of lighting or audio settings which correspond to different time periods. If you are familiar with earlier iterations of IE, this should be familiar, as this was how the default server lighting and server audio settings worked. Now though, packages are the universal way for determining lighting settings, meaning it’s possible to have multiple packages in-game and to freely switch between them. In the previous version of IE, there was essentially only a server audio and lighting package, and then region and weather settings applied a static change to the audio or lighting.

Here’s an example of why this behavior was changed

Example

Example scope: Region
Setting: Blacksmith Shop
Audio Package

Previous version of IE (no packages, just a standardized configuration of audio settings):
A player enters a blacksmith shop and a store ambience plays followed by randomized clanging sounds.

That’s cool and does the trick in a lot of circumstances. But this about creating immersive environments and the idea is to supercharge the ability for developers to fine tune their audio and lighting settings and boost the immersive quality of their games.

Current version of IE (packages):
A player enters the blacksmith shop and a store ambience plays followed by randomized clanging sounds. The store ambience rises and falls to different pitches and volumes depending on the time of day. As the day progresses, the sound of the ambience grows and climaxes around mid-day, the busy period. The randomization rates of the clanging increase, too, in order to simulate the audio sensation of more activity. As the shop nears the closing time, randomized sounds of the blacksmith yelling “Last call! Last call!” are played. At night, the ambience fades quietly and disappears.

That is the idea of what IE is supposed to support.

Package support is lent to everything now: server, region, and weather. This means that, rather than relying on server settings, you can actually chop up your entire map into regions, and directly tailor the audio and lighting packages that way. This way, you can fine tune your audio and lighting, if the literal environment conceivably impacts that. For example, the lighting and ambience of a city might be highly different from the lighting and ambience of a plain.

New API and Settings

API

Notes:

  • PackageName is the name of whatever your package is (this will be the folder name under Packages)
  • PackageType is always either “Audio” or “Lighting”
  • All API calls should be done from the server, with the exception of Main:Run() which should be called once from both the server and client

Main:Run()
This runs IE - call this before interacting with anything else in the API

Main:SetServerPackage(PackageType: string, PackageName: string)
This sets the server package.

Main:SetWeatherPackage(PackageType: string, PackageName: string)
This sets the weather package

Main:ClearWeather(PackageType: string, PackageName: string)
This clears the weather package

Reminder: regions are handled automatically, hence why there is not any API for them

Here is some example code:

Server


local ReplicatedStorage = game:GetService("ReplicatedStorage")

local IEFolder = ReplicatedStorage.IE

local IEMain = require(IEFolder.Main)

IEMain:Run()

IEMain:SetServerPackage("Audio", "Default")

IEMain:SetServerPackage("Lighting", "Default")

Client


local ReplicatedStorage = game:GetService("ReplicatedStorage")

local IEFolder = ReplicatedStorage:WaitForChild("IE")

local Main = require(IEFolder:WaitForChild("Main"))

Main:Run()

Assuming I have two packages, one audio package called “Default” and another lighting package called “Default”, this will work perfectly.

I highly recommend playing around in the example place to get an idea of how to deploy IE V2.

Settings are included and described within the module. They are very similar to the V1 settings with some changes, removals, and additions.

How is IE V2 Functionally Different, i.e. the Nitty Gritty?

Details

Firstly, IE V2 is different enough to the point where there is zero backwards compatibility with previous versions of IE or configurations. It’s really easy to switch over though, and specific instructions are provided in the following section.

How IE V1 worked

IE V1 worked by essentially running a package system on the server. When a player entered a region or when weather was generated, the server settings would be interrupted and the settings for the region or weather would be applied. As mentioned in the example above, this works for a lot of cases.

How IE V2 worked

IE V2 is way cleaner internally and works in a much smarter way. IE now can simultaneously process three packages simultaneously and apply the settings based on the specified scope. What this means is that when you enter a region, for example, the server package remains loaded in the background so that you can quickly and accurately switch back over to it when you leave the region. This is not performance intensive, and actually boosts performance by reducing the amount of times the client or server must read new packages.

IE is built to allow better direct control by the developer during run-time. V1 was very much of a “create your settings and let it run”. V2 captures that same spirit, so that IE remains useful to non-programmers and programmers alike, but allows for much-needed control to ensure that IE behaves exactly how you want it too.

IE is also compatible with CullingService. One of the big limitations to IE, was that I wasn’t able to use it in tandem with CullingService, because parts that were loaded in would not be adjusted by the lighting system. IE V2 fixes this, and allows for CullingService compatibility to be toggled on and off. This way, you can continue to maximize performance.

How to Switch from IE V1 iterations to IE V2

Conversion Steps

V2 is not backwards compatible with previous versions of IE. There are significant changes to the API which require you to ‘launch’ IE yourself. Below are instructions.

  1. Convert your previous lighting settings to Package format. To see how this is done, check out the example place. It’s pretty straight forward!
  2. Require Main
  3. Call Main:Run()
  4. Set your server package for both audio and lighting, using Main:SetServerPackage(“Audio”, PackageNameHere) and Main:SetServerPackage(“Lighting”, PackageNameHere)

A default lighting and audio package must be assigned to the server. If you don’t want server or audio packages, just create one with the same start and end times that has no changes. Internally, though, it’s important that there is one set

Legacy Downloads

IE V1 Legacy Model.rbxm (53.2 KB)
IE V1 Legacy Example Place.rbxl (82.9 KB)

Because IE V2 is not backwards compatible, the latest V1 variant has been included for your convenience. This should function perfectly fine, however, I highly recommend using IE V2 for more control.

Enjoy!

6 Likes

Hi,

The IE project looks good but I can’t see if you can play a sound based on the player? is it possible?

Julian

What do you mean by this? Like a sound that only a specific player would hear?

IE regions will play sounds that only player’s in the region can hear. Server sounds will be heard by all players, unless they are in a region (which takes priority). Weather sounds will also be heard by all players, unless they are in a region which has the Weather Exemption property ticked to yes.

Do the time periods work with regions? I was trying to use them but when the time passed the EndTime, the audio didn’t appear to change. Is this a bug or am I doing something wrong?

Yes, time periods work with regions. I recommend playing around with the example place, since the setting formatting is almost exactly the same for server settings. If you’re still having issues, I’d be happy to connect with you via Discord and walk you through the set-up/clarify any ambiguities.

I’m not sure if I worded it correctly but I meant continuous time periods as in the audio will change whilst still in the region once the time period changes. I noticed that when I exit and re enter the region the sound changes to the correct one for the current time period, even in the example place this behaviour is apparent so I am not entirely sure whether what I want works.

1 Like

It is intended to do that (have audio change based on the time, even in regions). If you’re able, could you PM/DM me a repro place file so that I can take a look and see if there is a settings error or if there is a bug in IE?

Umm what does this does and i keep getting this in the ouput

  Infinite yield possible on 'Workspace:WaitForChild("IERegions")'  -  Studio

It looks like you don’t have a folder within workspace called IERegions. If you check out the Example place here: Immersive Environments Testing - Roblox you should be able to see how that folder can be utilized to create audio and lighting regions. I highly recommend playing around with that place, since it will help you get familiar with the system.

If you’re still running into set-up issues, feel free to reach out to me individually, unless you think it’s a question that everyone would benefit from, in which case feel free to continue replying here.

ok

i am currently using your Culling Service great job on that module

more efficient then stream loading which is still buggy

1 Like

Bug Fix + Small Feature Addition

  • New Audio Component Setting (i.e., the things within your packages). Within your “GeneralSettings” you can now add “AllowOnlyOneRandomSound” (boolean) which will determine whether only one randomized sound is able to be played at once. This is useful for assigning music or soundtracks to a region and not having them overlap with other songs
  • Bug fix which previous throttled multiple randomized sounds from properly playing
  • Internal tracking improvements
  • Updated the example place with @Monstercat EDM so that people don’t think the module is broken (it’s just that the sounds weren’t updated with the Roblox audio update)

(All updates are published to GitHub, the Roblox Library, and the Example place)

1 Like

Here’s a suggestion for IE V2.

Audio component: More sound choices such as ReverbSoundEffect, EchoSoundEffect, EqualizerSoundEffect, DistortionSoundEffect, CompressorSoundEffect, ChorusSoundEffect, FlangeSoundEffect, PitchShiftSoundEffect, and TremoloSoundEffect.

Lighting component: More lighting choices such as clouds, TimeOfDay, GeographicLatitude, ClockTime, and skybox appearances.

1 Like

i keep getting this warning PackageType: nil, not found within PackageHandling in output and I don’t know the reason of the issue i have everything exactly placed the way you had it

Very cool. Definitely gonna use a multitude of features within my fps games!

I’ve been getting some errors in the Main script and I’m not sure what issues they cause or how to fix them.

Errors:

I’ve been messing around with this and I can’t seem to get sounds or lighting to be in a specific region. Also, for some reason the sun disappears and the time cycle doesn’t progress.

1 Like

Hi!

If you wouldn’t mind, could you shoot me a repro file with this? It’s like there’s a set-up error, but on the chance there’s an undiscovered bug it would help me to be able to see what you are seeing.

There’s an issue with the module that I’ve come across and can’t seem to rectify, does anyone know how to mute sounds that are parented to SoundService? The module isn’t allowing it because of the auto tweening that it does, makes it impossible to incorporate player’s personal settings in-game.

I’m assuming you have some setting for players to toggle that mutes sounds like sound effects (trying to make sure I understand the context/issue)? If that’s the case, I would recommend adjusting the package during run-time on the client (packages are not cached) and manually set the Volume property to 0 there.

Yes that’s spot on what I mean, if at all possible could you guide me to where it is that the changes should be made? There’s so much going on and fine tuned in the IE Modules that I’m not confident I’d do it properly nor efficiently.

No problem! Navigate to your package module at run-time (IE.Main.Packages.Audio[Region/Server/Weather][YourPackageName]) and within that you’ll have the component modules of your packages (in other words, all of the sub-modules that specify what settings are occurring at what times, that together define the package itself). Require the component modules and change the volume.

Packages can be modified at run-time, so regardless of if the volume isn’t initially defined (ex: modification of this package in demo place - https://github.com/httpsKingPie/Immersive-Environments/blob/main/src/ReplicatedStorage/IE/Packages/Audio/Region/JoinedRegion/JoinedRegion.lua)

Excerpt
["SharedSounds"] = {
	["Glow"] = {
		["SoundId"] = "7028856935",
		
		["Set"] = {
		
		},
		
		["Tween"] = {
			--// Volume is not defined
		},
	},
},

You can do:

--// Assuming IE is defined above
local Component = require(IE.Packages.Audio.Region.JoinedRegion)
Component["Shared Sounds"]["Glow"]["Tween"] = 0 --// or whatever you want this to be

That will ensure that all future changes keep the sound at 0. Make sure if the sound is currently playing in SoundService, that you change the volume there too.

Since IE does not cache, that’s the only change you need to do.

Of course, if you wanted something comprehensive, you could always loop through your package components and set all the Volume amounts to a preset amount or modify it

Example of setting all Region Package volume to 0 and adjusting any currently playing sounds
--// Assuming IE and SoundService are defined above
local ActiveRegionSounds: Folder = SoundService:WaitForChild("ActiveRegionSounds")
local SharedSounds: Folder = SoundService:WaitForChild("SharedSounds")
local ActiveServerSounds: Folder = SoundService:WaitForChild("ActiveServerSounds")

local RegionFolder: Folder = IE.Packages.Audio.Region
local AllRegionPackages: table = RegionFolder:GetChildren()

local NewVolumeAmount = 0 --// or whatever you want

local function FindExistingSound(SoundName: string)
	local ExistingSound: Sound | nil = ActiveRegionSounds:FindFirstChild(SoundName, true) or SharedSounds:FindFirstChild(SoundName, true) or ActiveServerSounds:FindFirstChild(SoundName, true)
	
	return ExistingSound
end

for _, Package: Folder in pairs (AllRegionPackages) do
	for _, PackageComponenet: ModuleScript in pairs (Package:GetChildren()) do
		local RequiredComponent = require(PackageComponent)
		
		--// Parse SharedSounds
		for SoundName: string, SoundSettings: table in pairs (RequiredComponent["SharedSounds"])
			SoundSettings["Tween"] = NewVolumeAmount
			
			local ExistingSound = FindExistingSound(SoundName)
			
			if ExistingSound then
				ExistingSound.Volume = NewVolumeAmount
			end
		end
		
		--// Parse RegionSounds
		for SoundName: string, SoundSettings: table in pairs (RequiredComponent["RegionSounds"])
			SoundSettings["Tween"] = NewVolumeAmount
			
			local ExistingSound: Sound | nil = FindExistingSound(SoundName)
			
			if ExistingSound then
				ExistingSound.Volume = NewVolumeAmount
			end
		end
		
		--// Parse RandomSounds
		for SoundName: string, SoundSettings: table in pairs (RequiredComponent["RandomSounds"])
			SoundSettings["Tween"] = NewVolumeAmount
			
			local ExistingSound = FindExistingSound(SoundName)
			
			if ExistingSound then
				ExistingSound.Volume = NewVolumeAmount
			end
		end
	end
end

And of course you could tailor the above code to do whatever you needed it to.


I hope that helps. Pardon any errors on the code, it was written untested in Notepad++, but regardless it should convey the general idea. Let me know if there’s anything I can expand upon.

1 Like