Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes some major sleepers, Refactors maploading to be async (100% lag free) #7659

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
0d80759
Removes a sleep loop from airlocks
PowerfulBacon Sep 9, 2022
1342094
Starts the ruin generation subsystem
PowerfulBacon Sep 9, 2022
0973c84
Implements the start of the map placer, with extra bugs
PowerfulBacon Sep 15, 2022
8d40725
Fixes the subsystem not working
PowerfulBacon Sep 18, 2022
9cdfff2
Bunch of bug fixes
PowerfulBacon Sep 18, 2022
f5f7779
Fixes the parameters getting sent wrong and pre-atom-init loading
PowerfulBacon Sep 20, 2022
cbe2633
Fixes the final map loads
PowerfulBacon Sep 30, 2022
22f987e
[TEMP] - Adds in debugging to the MC to track freezes
PowerfulBacon Sep 30, 2022
b91071e
Fixes multiple maps being placed at the same time breaking
PowerfulBacon Sep 30, 2022
dcc596f
Merge remote-tracking branch 'upstream/master' into Fixes-airlocks
PowerfulBacon Sep 30, 2022
20aca58
Fixes
PowerfulBacon Sep 30, 2022
040e249
Fixes to concurrent shuttle loading
PowerfulBacon Sep 30, 2022
3e7fedf
Merge remote-tracking branch 'upstream/master' into Fixes-airlocks
PowerfulBacon Sep 30, 2022
681ca00
Update stoplag.dm
PowerfulBacon Sep 30, 2022
84a05a5
Fixes the unit tests
PowerfulBacon Sep 30, 2022
5b25b05
Fixes lavaland ruins
PowerfulBacon Oct 2, 2022
95bedeb
Merge remote-tracking branch 'upstream/master' into Fixes-airlocks
PowerfulBacon Oct 3, 2022
40554b5
Merge remote-tracking branch 'upstream/master' into Fixes-airlocks
PowerfulBacon Nov 5, 2022
c059ed8
Minor fixes that could break things
PowerfulBacon Nov 5, 2022
a0d39a7
Fixes the shuttle loading bug while simultaneously making shuttle cod…
PowerfulBacon Nov 6, 2022
17dd06b
Address arch's reviews
PowerfulBacon Nov 6, 2022
5ae4a8c
Fixes infinite recursion
PowerfulBacon Nov 6, 2022
83f8412
Disables tick overrun debug
PowerfulBacon Nov 30, 2022
1141fe3
Adds in a bunch of error messages so I know whast going on
PowerfulBacon Nov 30, 2022
1eeaa7d
Update shuttles.dm
PowerfulBacon Dec 4, 2022
496aa55
Update shuttles.dm
PowerfulBacon Dec 4, 2022
c5db57c
This should fix the shuttle loading issue
PowerfulBacon Dec 7, 2022
e824fbc
Removes some logging msesages
PowerfulBacon Dec 8, 2022
2c511c6
Fixes the shuttle loading bug (Mappers who set width and height will …
PowerfulBacon Dec 8, 2022
755ea9c
Adds in a shuttle size unit test
PowerfulBacon Dec 8, 2022
dcb9343
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
cf41707
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
4eaf899
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
de68416
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
4dc737f
Fucks up the kilo shuttle
PowerfulBacon Dec 8, 2022
30ca478
Fucks up the kilo shuttle
PowerfulBacon Dec 8, 2022
c0a80ee
Merge branch 'Fixes-airlocks' of https://github.com/PowerfulBacon/Bee…
PowerfulBacon Dec 8, 2022
1ef6097
Try this
PowerfulBacon Dec 8, 2022
510cfc8
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
0df6449
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
d4d206e
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
b7eecdb
Deletes the MC warning
PowerfulBacon Dec 8, 2022
ae932d8
Fixes the mobile docking port path not accounting for subtypes
PowerfulBacon Dec 8, 2022
315b980
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
6322ff7
Update shuttle_width_height_correctness.dm
PowerfulBacon Dec 8, 2022
1c788c4
Revert "Fucks up the kilo shuttle"
PowerfulBacon Dec 8, 2022
8310a7c
Fixes the map and the bug
PowerfulBacon Dec 8, 2022
dd5e58c
Update _maps/shuttles/arrival/arrival_kilo.dmm
PowerfulBacon Dec 8, 2022
e241cfe
Fixes a bunch of messed up shuttles
PowerfulBacon Dec 8, 2022
1e5c7f0
Merge branch 'Fixes-airlocks' of https://github.com/PowerfulBacon/Bee…
PowerfulBacon Dec 8, 2022
24a3bc4
Merge remote-tracking branch 'upstream/master' into Fixes-airlocks
PowerfulBacon Dec 8, 2022
b4e60f4
Fixes flandstation
PowerfulBacon Dec 8, 2022
0638ad2
Resets pubby and fland
PowerfulBacon Dec 8, 2022
637cd09
Update FlandStation.dmm
PowerfulBacon Dec 8, 2022
aa005bc
PLEASE JUST RESET FLAND TO MASTER
PowerfulBacon Dec 8, 2022
4137da0
Update FlandStation.dmm
PowerfulBacon Dec 9, 2022
cb64842
Fixes flandstation
PowerfulBacon Dec 9, 2022
7ce7b43
Fixes fland fully
PowerfulBacon Dec 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion _maps/shuttles/arrival/arrival_kilo.dmm

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions beestation.dme
Expand Up @@ -358,6 +358,7 @@
#include "code\controllers\subsystem\language.dm"
#include "code\controllers\subsystem\lighting.dm"
#include "code\controllers\subsystem\machines.dm"
#include "code\controllers\subsystem\map_generator.dm"
#include "code\controllers\subsystem\mapping.dm"
#include "code\controllers\subsystem\materials.dm"
#include "code\controllers\subsystem\metrics.dm"
Expand Down Expand Up @@ -454,6 +455,7 @@
#include "code\datums\progressbar.dm"
#include "code\datums\radiation_wave.dm"
#include "code\datums\recipe.dm"
#include "code\datums\ref.dm"
#include "code\datums\ruins.dm"
#include "code\datums\saymode.dm"
#include "code\datums\shuttles.dm"
Expand Down Expand Up @@ -714,6 +716,8 @@
#include "code\datums\looping_sounds\item_sounds.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
#include "code\datums\looping_sounds\weather.dm"
#include "code\datums\map_generators\_map_generator.dm"
#include "code\datums\map_generators\map_placer.dm"
#include "code\datums\mapgen\_MapGenerator.dm"
#include "code\datums\mapgen\CaveGenerator.dm"
#include "code\datums\mapgen\JungleGenerator.dm"
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/MC.dm
Expand Up @@ -96,3 +96,6 @@
ss_id="processing_[#X]";\
}\
/datum/controller/subsystem/processing/##X

//If the MC goes for longer than 5 seconds, provide a warning for investigation
#define MASTER_CONTROLLER_DELAY_WARN_TIME 2 SECONDS
2 changes: 2 additions & 0 deletions code/__DEFINES/maps.dm
Expand Up @@ -124,3 +124,5 @@ require only minor tweaks.
///Hint for whether a genturf should generate as a closed or open turf. null for default.
#define GENTURF_HINT_OPEN "open"
#define GENTURF_HINT_CLOSED "closed"

#define SPACE_KEY "space"
9 changes: 9 additions & 0 deletions code/__HELPERS/stoplag.dm
Expand Up @@ -5,17 +5,26 @@

/// Returns the number of ticks slept
/proc/stoplag(initial_delay)
//No master controller active, sleep for the tick lag to allow other things to run
if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT))
sleep(world.tick_lag)
return 1
//Set the default initial delay, if one isn't provided
if (!initial_delay)
initial_delay = world.tick_lag
. = 0
//Begin tracking if we are in debugging
//Calculate the delay in terms of ticks
var/i = DS2TICKS(initial_delay)
do
//Increment the total amount of time slept
. += CEILING(i*DELTA_CALC, 1)
//Sleep and allow other processes to run
sleep(i*world.tick_lag*DELTA_CALC)
//Sleep for double the time as before, sleeping incurs overhead so the longer something sleeps
//the less we check for wake ups
i *= 2
//Repeat until we have some tick left
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))

#undef DELTA_CALC
Expand Down
7 changes: 7 additions & 0 deletions code/controllers/master.dm
Expand Up @@ -324,6 +324,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/list/subsystems_to_check
//the actual loop.

var/anti_tick_contention_sleep_time = 0

while (1)
tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
var/starting_tick_usage = TICK_USAGE
Expand All @@ -338,9 +340,14 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if (starting_tick_usage > TICK_LIMIT_MC) //if there isn't enough time to bother doing anything this tick, sleep a bit.
sleep_delta *= 2
current_ticklimit = TICK_LIMIT_RUNNING * 0.5
anti_tick_contention_sleep_time += world.tick_lag * (processing * sleep_delta)
if (anti_tick_contention_sleep_time > MASTER_CONTROLLER_DELAY_WARN_TIME)
log_runtime("Warning: The Master Controller has been sleeping for [anti_tick_contention_sleep_time]ds which may result in game freezing.")
sleep(world.tick_lag * (processing * sleep_delta))
continue

anti_tick_contention_sleep_time = 0

//Byond resumed us late. assume it might have to do the same next tick
if (last_run + CEILING(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time)
sleep_delta += 1
Expand Down
6 changes: 6 additions & 0 deletions code/controllers/subsystem/air.dm
Expand Up @@ -381,6 +381,9 @@ SUBSYSTEM_DEF(air)
currentrun.len--
if(M == null)
atmos_machinery.Remove(M)
// Prevents uninitalized atmos machinery from processing.
if (!(M.flags_1 & INITIALIZED_1))
continue
if(!M || (M.process_atmos() == PROCESS_KILL))
atmos_machinery.Remove(M)
if(MC_TICK_CHECK)
Expand All @@ -395,6 +398,9 @@ SUBSYSTEM_DEF(air)
while(currentrun.len)
var/obj/machinery/M = currentrun[currentrun.len]
currentrun.len--
// Prevents uninitalized atmos machinery from processing.
if (!(M.flags_1 & INITIALIZED_1))
continue
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
atmos_air_machinery.Remove(M)
if(MC_TICK_CHECK)
Expand Down
9 changes: 9 additions & 0 deletions code/controllers/subsystem/atoms.dm
Expand Up @@ -27,6 +27,15 @@ SUBSYSTEM_DEF(atoms)
initialized = INITIALIZATION_INSSATOMS

/datum/controller/subsystem/atoms/Initialize(timeofday)
//Wait until map loading is completed
if (length(SSmap_generator.executing_generators) > 0)
to_chat(world, "<span class='boldannounce'>Waiting for [length(SSmap_generator.executing_generators)] map generators...</bold>")
do
SSmap_generator.fire()
sleep(0.5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this sleep for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since fire() is tick checked, if it overruns then the proc will cancel. Without the sleep, byond will trigger the fire() again, which will do nothing since the tick check just instantly fails. The sleep allows the game to process to the next tick, so that the MC_TICK_CHECKs inside fire() can run again. Works similarly to the same way the main MC loop works

while (length(SSmap_generator.executing_generators) > 0)
to_chat(world, "<span class='boldannounce'>Map generators completed, initializing atoms.</bold>")

GLOB.fire_overlay.appearance_flags = RESET_COLOR
setupGenetics() //to set the mutations' sequence
initialized = INITIALIZATION_INNEW_MAPLOAD
Expand Down
54 changes: 54 additions & 0 deletions code/controllers/subsystem/map_generator.dm
@@ -0,0 +1,54 @@
SUBSYSTEM_DEF(map_generator)
name = "Map Generator"
wait = 1
flags = SS_TICKER | SS_NO_INIT
runlevels = ALL

/// List of all currently executing generator datums
var/list/executing_generators = list()

/// Index of current run
var/current_run_index

/// Length of current run
var/current_run_length

/datum/controller/subsystem/map_generator/stat_entry()
var/list/things = list()
for(var/datum/map_generator/running_generator as() in executing_generators)
things += "{Ticks: [running_generator.ticks]}"
. = ..("GenCnt:[length(executing_generators)], [things.Join(",")]")

/datum/controller/subsystem/map_generator/fire()
if (!length(executing_generators))
return
//Reset the queue
if (current_run_index > current_run_length || !current_run_length)
current_run_index = 1
current_run_length = length(executing_generators)
//Split the tick
MC_SPLIT_TICK_INIT(current_run_length)
//Start processing
while (current_run_index <= current_run_length)
//Get current action
var/datum/map_generator/currently_running = executing_generators[current_run_index]
current_run_index ++
//Perform generate action
var/completed = TRUE
while (!currently_running.execute_run())
// We overused our allocated amount of tick
if(MC_TICK_CHECK)
completed = FALSE
break
//We completed
if (completed)
currently_running.complete()
//Remove the currently running generator
executing_generators -= currently_running
//Decrement the current run nidex
current_run_index --
//Decrement the current run length
current_run_length --
//to_chat(world, "<span class='announce'>Fully completed running map generator [current_run_index + 1].</span>")
//Continue to the next process
MC_SPLIT_TICK
97 changes: 57 additions & 40 deletions code/controllers/subsystem/shuttle.dm
Expand Up @@ -57,9 +57,10 @@ SUBSYSTEM_DEF(shuttle)

var/obj/docking_port/mobile/existing_shuttle

var/obj/docking_port/mobile/preview_shuttle
var/datum/map_template/shuttle/preview_template

var/obj/docking_port/mobile/preview_shuttle

var/datum/turf_reservation/preview_reservation

var/shuttles_loaded = FALSE
Expand Down Expand Up @@ -548,7 +549,6 @@ SUBSYSTEM_DEF(shuttle)

existing_shuttle = SSshuttle.existing_shuttle

preview_shuttle = SSshuttle.preview_shuttle
preview_template = SSshuttle.preview_template

preview_reservation = SSshuttle.preview_reservation
Expand Down Expand Up @@ -627,19 +627,21 @@ SUBSYSTEM_DEF(shuttle)
QDEL_LIST(remove_images)


/datum/controller/subsystem/shuttle/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port)
// Check for an existing preview
if(preview_shuttle && (loading_template != preview_template))
preview_shuttle.jumpToNullSpace()
preview_shuttle = null
preview_template = null
QDEL_NULL(preview_reservation)
/datum/controller/subsystem/shuttle/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port, datum/variable_ref/loaded_shuttle_reference)
if (!loaded_shuttle_reference)
loaded_shuttle_reference = new()
var/datum/map_generator/shuttle_loader = load_template(loading_template, loaded_shuttle_reference)
shuttle_loader.on_completion(CALLBACK(src, .proc/linkup_shuttle_after_load, loading_template, destination_port, loaded_shuttle_reference))
shuttle_loader.on_completion(CALLBACK(src, .proc/action_load_completed, destination_port, loaded_shuttle_reference))
preview_template = loading_template
return shuttle_loader

if(!preview_shuttle)
if(load_template(loading_template))
preview_shuttle.linkup(loading_template, destination_port)
preview_template = loading_template
/datum/controller/subsystem/shuttle/proc/linkup_shuttle_after_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port, datum/variable_ref/shuttle_reference)
var/obj/docking_port/mobile/loaded_shuttle = shuttle_reference.value
loaded_shuttle.linkup(loading_template, destination_port)

/datum/controller/subsystem/shuttle/proc/action_load_completed(obj/docking_port/stationary/destination_port, datum/variable_ref/shuttle_reference)
var/obj/docking_port/mobile/loaded_shuttle = shuttle_reference.value
// get the existing shuttle information, if any
var/timer = 0
var/mode = SHUTTLE_IDLE
Expand All @@ -653,55 +655,59 @@ SUBSYSTEM_DEF(shuttle)
D = existing_shuttle.docked

if(!D)
D = generate_transit_dock(preview_shuttle)
D = generate_transit_dock(loaded_shuttle)

if(!D)
CRASH("No dock found for preview shuttle ([preview_template.name]), aborting.")

var/result = preview_shuttle.canDock(D)
var/result = loaded_shuttle.canDock(D)
// truthy value means that it cannot dock for some reason
// but we can ignore the someone else docked error because we'll
// be moving into their place shortly
if((result != SHUTTLE_CAN_DOCK) && (result != SHUTTLE_SOMEONE_ELSE_DOCKED))
WARNING("Template shuttle [preview_shuttle] cannot dock at [D] ([result]).")
WARNING("Template shuttle [loaded_shuttle] cannot dock at [D] ([result]).")
return

if(existing_shuttle)
existing_shuttle.jumpToNullSpace()

var/list/force_memory = preview_shuttle.movement_force
preview_shuttle.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
preview_shuttle.initiate_docking(D)
preview_shuttle.movement_force = force_memory
var/list/force_memory = loaded_shuttle.movement_force
loaded_shuttle.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
loaded_shuttle.initiate_docking(D)
loaded_shuttle.movement_force = force_memory

. = preview_shuttle
. = loaded_shuttle

// Shuttle state involves a mode and a timer based on world.time, so
// plugging the existing shuttles old values in works fine.
preview_shuttle.timer = timer
preview_shuttle.mode = mode
loaded_shuttle.timer = timer
loaded_shuttle.mode = mode

preview_shuttle.register()
loaded_shuttle.register()

preview_shuttle.reset_air()
loaded_shuttle.reset_air()

// TODO indicate to the user that success happened, rather than just
// blanking the modification tab
preview_shuttle = null
preview_template = null
existing_shuttle = null
selected = null
QDEL_NULL(preview_reservation)

/datum/controller/subsystem/shuttle/proc/load_template(datum/map_template/shuttle/S)
/datum/controller/subsystem/shuttle/proc/load_template(datum/map_template/shuttle/S, datum/variable_ref/shuttle_reference)
. = FALSE
// load shuttle template, centred at shuttle import landmark,
preview_reservation = SSmapping.RequestBlockReservation(S.width, S.height, SSmapping.transit.z_value, /datum/turf_reservation/transit)
if(!preview_reservation)
CRASH("failed to reserve an area for shuttle template loading")
var/turf/BL = TURF_FROM_COORDS_LIST(preview_reservation.bottom_left_coords)
S.load(BL, centered = FALSE, register = FALSE)
var/datum/map_generator/shuttle_loader = S.load(BL, FALSE, TRUE, TRUE, FALSE)
shuttle_loader.on_completion(CALLBACK(src, .proc/template_loaded, S, BL, shuttle_reference))
return shuttle_loader

/// Template loaded completed.
/// Parameters preceeded by _ are discarded and not used.
/datum/controller/subsystem/shuttle/proc/template_loaded(datum/map_template/shuttle/S, turf/BL, datum/variable_ref/shuttle_reference)
var/affected = S.get_affected_turfs(BL, centered=FALSE)

var/found = 0
Expand All @@ -718,7 +724,7 @@ SUBSYSTEM_DEF(shuttle)
qdel(P, force=TRUE)
log_world("Map warning: Shuttle Template [S.mappath] has multiple mobile docking ports.")
else
preview_shuttle = P
shuttle_reference.value = P
if(!found)
var/msg = "load_template(): Shuttle Template [S.mappath] has no mobile docking port. Aborting import."
for(var/T in affected)
Expand All @@ -729,7 +735,7 @@ SUBSYSTEM_DEF(shuttle)
WARNING(msg)
return
//Everything fine
S.post_load(preview_shuttle)
S.post_load(shuttle_reference.value)
return TRUE

/datum/controller/subsystem/shuttle/proc/unload_preview()
Expand Down Expand Up @@ -860,10 +866,10 @@ SUBSYSTEM_DEF(shuttle)
if(S)
. = TRUE
unload_preview()
load_template(S)
if(preview_shuttle)
preview_template = S
user.forceMove(get_turf(preview_shuttle))
var/datum/variable_ref/loaded_shuttle_reference = new()
var/datum/map_generator/shuttle_loader = load_template(S, loaded_shuttle_reference)
shuttle_loader.on_completion(CALLBACK(src, .proc/jump_to_preview, user, loaded_shuttle_reference))
preview_template = S
if("load")
if(existing_shuttle == backup_shuttle)
// TODO make the load button disabled
Expand All @@ -873,9 +879,20 @@ SUBSYSTEM_DEF(shuttle)
else if(S)
. = TRUE
// If successful, returns the mobile docking port
var/obj/docking_port/mobile/mdp = action_load(S)
if(mdp)
user.forceMove(get_turf(mdp))
message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.")
log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.</span>")
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]")
var/datum/variable_ref/loaded_shuttle_reference = new()
var/datum/map_generator/shuttle_loader = action_load(S, null, loaded_shuttle_reference)
shuttle_loader.on_completion(CALLBACK(src, .proc/shuttle_manipulator_on_load, user, loaded_shuttle_reference))

/datum/controller/subsystem/shuttle/proc/shuttle_manipulator_on_load(mob/user, datum/variable_ref/loaded_shuttle_reference)
var/obj/docking_port/mobile/mdp = loaded_shuttle_reference.value
if(mdp)
user.forceMove(get_turf(mdp))
message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.")
log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.</span>")
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]")

/datum/controller/subsystem/shuttle/proc/jump_to_preview(mob/user, datum/variable_ref/loaded_shuttle_reference)
var/obj/docking_port/mobile/loaded_shuttle = loaded_shuttle_reference.value
preview_shuttle = loaded_shuttle_reference.value
if(loaded_shuttle)
user.forceMove(get_turf(loaded_shuttle))