Skip to content

Commit

Permalink
Ties Active Turfs to SSair Windows + Makes Turf Activation Direction …
Browse files Browse the repository at this point in the history
…Agnostic (tgstation#86602)

## About The Pull Request

[Ties new active turfs to SSair's "frame
window"](tgstation@cf46d8b)

Currently, if you add a new active turf midway through processing, it
will be handled as a PART of that fire's processing.

This combined with some bullshit with archive means that placing one
source of diffs down can lead to a 1 tick spread instantly, ONLY if no
turfs are actually active.

(The following is one tick of atmos processing)


![image](https://github.com/user-attachments/assets/189b3492-e1d7-496d-ae35-3a0c86d6c5fb)

![image](https://github.com/user-attachments/assets/1582f3ff-4d41-458b-b37b-daa925e856e0)

This runs counter to the existing archiving system, and violates the
principles of active/inactive turfs of being an optimization over
processing every cell individually.

The fix is to uh, not do that.

It also solves the highly edge case of a turf that's activated by
something reacting to its temp change, alone in a 1x1 with no neighbors
possibly causing an infinte stall in ssair.

I'm also cleaning up add to active a bit, zypher's idea should have 0
cost.

[Makes turf to turf activation fully diamond
shaped](tgstation@2528fb2)

Turf sharing operates off the archived gas list, but the check to see if
we SHOULD share was working off the normal gas/temp values.

This meant diff evening out was DIRECTIONAL (due to the directional
ordering of atmos adjacent turfs)

This is fixable by just using archive for these things.

This does require an additional arg to compare() which DOES matter at
this scale but I don't want to split compare into two procs I don't
think and it should be relatively minimal.

This means cleaner debug outputs, hopefully less pointlessly activated
turfs, and a more consistent activation/sharing order (we aren't
dropping turfs randomly now!)



https://github.com/user-attachments/assets/347d3cd6-542f-48e6-aa83-40e7e9b11635

(spreading w/o this change as an example of the former issues)


https://github.com/user-attachments/assets/da1ecbce-28b6-4241-8ac6-517b690c9ba6

---------

Co-authored-by: Kylerace <[email protected]>
  • Loading branch information
LemonInTheDark and Kylerace authored Sep 13, 2024
1 parent aea1589 commit 533e5c4
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 26 deletions.
35 changes: 16 additions & 19 deletions code/controllers/subsystem/air.dm
Original file line number Diff line number Diff line change
Expand Up @@ -488,29 +488,26 @@ SUBSYSTEM_DEF(air)
T.excited = FALSE

///Adds a turf to active processing, handles duplicates. Call this with blockchanges == TRUE if you want to nuke the assoc excited group
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = FALSE)
if(istype(T) && T.air)
T.significant_share_ticker = 0
if(blockchanges && T.excited_group) //This is used almost exclusivly for shuttles, so the excited group doesn't stay behind
T.excited_group.garbage_collect() //Nuke it
if(T.excited) //Don't keep doing it if there's no point
/datum/controller/subsystem/air/proc/add_to_active(turf/open/activate, blockchanges = FALSE)
if(istype(activate) && activate.air)
activate.significant_share_ticker = 0
if(blockchanges && activate.excited_group) //This is used almost exclusivly for shuttles, so the excited group doesn't stay behind
activate.excited_group.garbage_collect() //Nuke it
if(activate.excited) //Don't keep doing it if there's no point
return
#ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour(COLOR_VIBRANT_LIME, TEMPORARY_COLOUR_PRIORITY)
activate.add_atom_colour(COLOR_VIBRANT_LIME, TEMPORARY_COLOUR_PRIORITY)
#endif
T.excited = TRUE
active_turfs += T
if(currentpart == SSAIR_ACTIVETURFS)
currentrun += T
else if(T.flags_1 & INITIALIZED_1)
for(var/turf/S in T.atmos_adjacent_turfs)
add_to_active(S, TRUE)
activate.excited = TRUE
active_turfs += activate
else if(activate.flags_1 & INITIALIZED_1)
for(var/turf/neighbor as anything in activate.atmos_adjacent_turfs)
add_to_active(neighbor, TRUE)
else if(map_loading)
if(queued_for_activation)
queued_for_activation[T] = T
return
queued_for_activation[activate] = activate
else
T.requires_activation = TRUE
activate.requires_activation = TRUE

/datum/controller/subsystem/air/StartLoadingMap()
LAZYINITLIST(queued_for_activation)
Expand Down Expand Up @@ -560,8 +557,8 @@ SUBSYSTEM_DEF(air)
if(enemy_tile.current_cycle == -INFINITE)
continue
// .air instead of .return_air() because we can guarantee that the proc won't do anything
if(potential_diff.air.compare(enemy_tile.air))
//testing("Active turf found. Return value of compare(): [T.air.compare(enemy_tile.air)]")
if(potential_diff.air.compare(enemy_tile.air, MOLES))
//testing("Active turf found. Return value of compare(): [T.air.compare(enemy_tile.air, MOLES)]")
if(!potential_diff.excited)
potential_diff.excited = TRUE
SSair.active_turfs += potential_diff
Expand Down
4 changes: 2 additions & 2 deletions code/modules/atmospherics/environmental/LINDA_turf_tile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@
our_excited_group = excited_group //update our cache
if(our_excited_group && enemy_excited_group && enemy_tile.excited) //If you're both excited, no need to compare right?
should_share_air = TRUE
else if(our_air.compare(enemy_air)) //Lets see if you're up for it
else if(our_air.compare(enemy_air, ARCHIVE)) //Lets see if you're up for it
SSair.add_to_active(enemy_tile) //Add yourself young man
var/datum/excited_group/existing_group = our_excited_group || enemy_excited_group || new
if(!our_excited_group)
Expand Down Expand Up @@ -332,7 +332,7 @@
var/datum/gas_mixture/planetary_mix = SSair.planetary[initial_gas_mix]
// archive ourself again so we don't accidentally share more gas than we currently have
LINDA_CYCLE_ARCHIVE(src)
if(our_air.compare(planetary_mix))
if(our_air.compare(planetary_mix, ARCHIVE))
if(!our_excited_group)
var/datum/excited_group/new_group = new
new_group.add_turf(src)
Expand Down
15 changes: 10 additions & 5 deletions code/modules/atmospherics/gasmixtures/gas_mixture.dm
Original file line number Diff line number Diff line change
Expand Up @@ -451,16 +451,17 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//thermal energy of the system (self and sharer) is unchanged

///Compares sample to self to see if within acceptable ranges that group processing may be enabled
///Takes the gas index to read from as a second arg (either MOLES or ARCHIVE)
///Returns: a string indicating what check failed, or "" if check passes
/datum/gas_mixture/proc/compare(datum/gas_mixture/sample)
/datum/gas_mixture/proc/compare(datum/gas_mixture/sample, index)
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
var/list/cached_gases = gases
var/moles_sum = 0

for(var/id in cached_gases | sample_gases) // compare gases from either mixture
// Yes this is actually fast. I too hate it here
var/gas_moles = cached_gases[id]?[MOLES] || 0
var/sample_moles = sample_gases[id]?[MOLES] || 0
var/gas_moles = cached_gases[id]?[index] || 0
var/sample_moles = sample_gases[id]?[index] || 0
// Brief explanation. We are much more likely to not pass this first check then pass the first and fail the second
// Because of this, double calculating the delta is FASTER then inserting it into a var
if(abs(gas_moles - sample_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
Expand All @@ -470,8 +471,12 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
moles_sum += gas_moles

if(moles_sum > MINIMUM_MOLES_DELTA_TO_MOVE) //Don't consider temp if there's not enough mols
if(abs(temperature - sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
if(index == ARCHIVE)
if(abs(temperature_archived - sample.temperature_archived) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
else
if(abs(temperature - sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"

return ""

Expand Down

0 comments on commit 533e5c4

Please sign in to comment.