Need advice on how to handle an insulation system

I’m trying to make a system to judge weather exposure on a player- so if someone is outside during a blizzard, for example, they eventually die. The issue is, I want it to work for rooms of any shape, and detect if they have holes.

My previous version of this did a raycast up, and then in every cardinal direction (north, east, etc), but it had weaknesses- detecting a large room was one. If the raycasts detected too far, it’d consider a player sheltered even if they were outside. If it was too short, big rooms didnt count as shelter.

Im aware this is a bit of an unconventional post- I hope this is the right category? I dont want anyone to make the system for me, or design it for me, but I could really use the help with where to start on a system this (seemingly) complex.

Thank you in advance, hope this makes sense! <3

Hi, I have written down a couple of approaches for this. Some are “out there” but maybe they could give you some ideas.

Region3 / Spatial Partitioning

  • Instead of checking just around the player, define precomputed “indoor” areas using Region3.
  • When a player enters a space, check if they’re inside a known safe region instead of raycasting every frame.
  • This works well if buildings are mostly static and don’t change often.
  • If structures are destructible, you’d need to update the safe regions dynamically.

Flood Fill with Spatial Queries

  • Start from the player’s position and perform a flood fill (expanding outward).
  • Use Workspace:FindPartOnRay to check if the flood can reach the sky.
  • If it can, the player is exposed. If not, they’re indoors.
  • Performance might be a concern, so you could limit how often it runs or use a queue-based approach (checking only a few points per frame).

Raycast Approach: Simple Sky Check

  1. Raycasting Upwards
  • Fire a single ray straight upwards from the player’s position.
  • If the ray hits something (like a ceiling, roof, or structure), mark the player as indoors.
  • If the ray doesn’t hit anything, mark the player as outside.
  • This avoids the complexity of multi-directional raycasts and focuses only on the key factor—the sky.
  1. Zones for Environment Type
  • Use regions or parts to define “zones” in your game world. These zones can represent areas like cold, hot, normal, etc.
  • When the player is outside, check if they are in a cold zone (could be marked with CollectionService tags or Region3 bounds).
  • If they are, treat them as being in a cold environment (exposed to the elements). If not, they are in a normal or warm zone.
  1. Combining the Two
  • When a player is outside and in a cold zone, trigger whatever “exposure” mechanic you have (like health decay or status effects).
  • Inside zones, no weather effect.

Benefits of This Approach

  • It’s simple and doesn’t require complex pathfinding or flood fills.
  • Performance-friendly since it only involves a basic upward raycast and checking zone tags.
  • Easily extendable to other types of environments like hot or toxic zones—just add more zones with corresponding effects.
  • Works well with static structures and player-built environments, as long as the “zones” are properly defined.

I hope this helps :slight_smile:

Approach 1 doesn’t really fit, because the players are going to be making their own buildings (ideally).

Approach 2 doesn’t make sense, and is referring to a deprecated function. I don’t know how to perform a flood fill.

Approach 3 is too simple; it means you can stand beneath a tiny piece of wood and it’ll be the same as a house.

Approach 3 fix
you can make a size threshold on the referenced part

game:GetService("RunService").Heartbeat:Connect(function(dt)
local Camera = workspace.CurrentCamera
	local perams = RaycastParams.new()
	perams.FilterDescendantsInstances = {workspace}
	perams.FilterType = Enum.RaycastFilterType.Whitelist
	local something1 = workspace:Raycast(Camera.CFrame.Position, Vector3.new(0, 200, 0), perams)
	if something1 and something1.Instance.CanCollide and something1.Instance.Transparency < 0.8
		and something1.Instance.Size.X > 5
		and something1.Instance.Size.Y > 0.4
		and something1.Instance.Size.Z > 5 then
		-- if player is under a building
	else
		-- if player is not under a building
	end
end)

Also heres an example of a flood fill

I don’t really understand what’s going on in this, but I’ll research it when I’m finished more basic systems. Marking this as solution, thank you :+1:

no problem :slight_smile: im happy you found a solution

1 Like