/**
* CarnMC
*
* Simplified MC; designed to fail fast and respawn.
* This ensures Master.process() never doubles up.
* It will kill itself and any sleeping procs if needed.
*
* All core systems are subsystems.
* They are process()'d by this Master Controller.
**/
var/global/datum/controller/master/Master = new()
/datum/controller/master
name = "Master"
// The minimum length of time between MC ticks (in deciseconds).
// The highest this can be without affecting schedules is the GCD of all subsystem waits.
// Set to 0 to disable all processing.
var/processing_interval = 1
// The iteration of the MC.
var/iteration = 0
// The cost (in deciseconds) of the MC loop.
var/cost = 0
// A list of subsystems to process().
var/list/subsystems = list()
// The cost of running the subsystems (in deciseconds).
var/subsystem_cost = 0
// The type of the last subsystem to be process()'d.
var/last_type_processed
/datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
if(Master != src)
if(istype(Master))
Recover()
qdel(Master)
else
init_subtypes(/datum/subsystem, subsystems)
Master = src
processing_interval = calculate_gcd()
/datum/controller/master/Destroy()
..()
// Tell qdel() to Del() this object.
return QDEL_HINT_HARDDEL_NOW
/datum/controller/master/proc/Recover()
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for(var/varname in Master.vars)
switch(varname)
if("name", "tag", "bestF", "type", "parent_type", "vars", "statclick") // Built-in junk.
continue
else
var/varval = Master.vars[varname]
if(istype(varval, /datum)) // Check if it has a type var.
var/datum/D = varval
msg += "\t [varname] = [D.type]\n"
else
msg += "\t [varname] = [varval]\n"
world.log << msg
subsystems = Master.subsystems
/datum/controller/master/proc/Setup(zlevel = 0)
set background = 1
preloadTemplates()
// Pick a random away mission.
//createRandomZlevel()
// Generate wasteland.
//make_mining_wasteland_secrets()
// Set up Z-level transistions.
setup_map_transitions()
world << "<span class='boldannounce'>Initializing subsystems...</span>"
sortTim(subsystems, /proc/cmp_subsystem_priority)
// Per-Z-level subsystems.
if (zlevel && zlevel > 0 && zlevel <= world.maxz)
for(var/datum/subsystem/SS in subsystems)
SS.Initialize(world.timeofday, zlevel)
sleep(-1)
else
for(var/datum/subsystem/SS in subsystems)
SS.Initialize(world.timeofday, zlevel)
sleep(-1)
sortTim(subsystems, /proc/cmp_subsystem_display)
// Set world options.
world.sleep_offline = 1
world.fps = config.fps
sleep(-1)
// Loop.
Master.process()
// Notify the MC that the round has started.
/datum/controller/master/proc/RoundStart()
for(var/datum/subsystem/SS in subsystems)
SS.can_fire = 1
SS.next_fire = world.time + rand(0, SS.wait) // Stagger subsystems.
// Used to smooth out costs to try and avoid oscillation.
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
/datum/controller/master/process()
if(!Failsafe)
new/datum/controller/failsafe() // (re)Start the failsafe.
spawn(0)
// Schedule the first run of the Subsystems.
var/timer = world.time
for(var/datum/subsystem/SS in subsystems)
timer += processing_interval
SS.next_fire = timer
var/start_time
while(1) // More efficient than recursion, 1 to avoid an infinite loop.
if(processing_interval > 0)
++iteration
var/startingtick = world.time // Store when we started this iteration.
start_time = world.timeofday
var/ran_subsystems = 0
for(var/datum/subsystem/SS in subsystems)
if(SS.can_fire > 0)
if(SS.next_fire <= world.time && SS.last_fire + (SS.wait * 0.5) <= world.time) // Check if it's time.
ran_subsystems = 1
timer = world.timeofday
last_type_processed = SS.type
SS.last_fire = world.time
SS.fire() // Fire the subsystem and record the cost.
SS.cost = MC_AVERAGE(SS.cost, world.timeofday - timer)
if(SS.dynamic_wait) // Adjust wait depending on lag.
var/oldwait = SS.wait
var/global_delta = (subsystem_cost - (SS.cost / (SS.wait / 10))) - 1
var/newwait = (SS.cost - SS.dwait_buffer + global_delta) * SS.dwait_delta
newwait = newwait * (world.cpu / 100 + 1)
newwait = MC_AVERAGE(oldwait, newwait)
SS.wait = Clamp(newwait, SS.dwait_lower, SS.dwait_upper)
if(oldwait != SS.wait)
processing_interval = calculate_gcd()
SS.next_fire += SS.wait
++SS.times_fired
// If we caused BYOND to miss a tick, stop processing for a bit...
if(startingtick < world.time || start_time + 1 < world.timeofday)
break
sleep(-1)
cost = MC_AVERAGE(cost, world.timeofday - start_time)
if(ran_subsystems)
var/oldcost = subsystem_cost
var/newcost = 0
for(var/datum/subsystem/SS in subsystems)
if (!SS.can_fire)
continue
newcost += SS.cost / (SS.wait / 10)
subsystem_cost = MC_AVERAGE(oldcost, newcost)
var/extrasleep = 0
// If we caused BYOND to miss a tick, sleep a bit extra...
if(startingtick < world.time || start_time + 1 < world.timeofday)
extrasleep += world.tick_lag * 2
// If we are loading the server too much, sleep a bit extra...
if(world.cpu > 80)
extrasleep += extrasleep + processing_interval
sleep(processing_interval + extrasleep)
else
sleep(50)
#undef MC_AVERAGE
// Determine the GCD of subsystem waits: the longest the MC can wait while still staying on schedule.
/datum/controller/master/proc/calculate_gcd()
var/GCD
// The shortest possible fire rate is the lowest of two ticks or 1 decisecond.
var/minimumInterval = min(world.tick_lag * 2, 1)
// Loop over each subsystem and determine the GCD based on its wait value.
for(var/datum/subsystem/SS in subsystems)
if(SS.wait)
GCD = Gcd(round(SS.wait * 10), GCD)
GCD = round(GCD)
// If the GCD is less than the minimum, just use the minimum.
if(GCD < minimumInterval * 10)
GCD = minimumInterval * 10
// Return GCD.
return GCD / 10
/datum/controller/master/proc/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
stat("Master Controller:", statclick.update("[round(Master.cost, 0.001)]ds (Interval: [Master.processing_interval] | Iteration:[Master.iteration])"))
/**
* CarnMC
*
* Simplified MC; designed to fail fast and respawn.
* This ensures Master.process() never doubles up.
* It will kill itself and any sleeping procs if needed.
*
* All core systems are subsystems.
* They are process()'d by this Master Controller.
**/
var/global/datum/controller/master/Master = new()
/datum/controller/master
name = "Master"
// The minimum length of time between MC ticks (in deciseconds).
// The highest this can be without affecting schedules is the GCD of all subsystem waits.
// Set to 0 to disable all processing.
var/processing_interval = 1
// The iteration of the MC.
var/iteration = 0
// The cost (in deciseconds) of the MC loop.
var/cost = 0
// A list of subsystems to process().
var/list/subsystems = list()
// The cost of running the subsystems (in deciseconds).
var/subsystem_cost = 0
// The type of the last subsystem to be process()'d.
var/last_type_processed
/datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
if(Master != src)
if(istype(Master))
Recover()
qdel(Master)
else
init_subtypes(/datum/subsystem, subsystems)
Master = src
processing_interval = calculate_gcd()
/datum/controller/master/Destroy()
..()
// Tell qdel() to Del() this object.
return QDEL_HINT_HARDDEL_NOW
/datum/controller/master/proc/Recover()
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for(var/varname in Master.vars)
switch(varname)
if("name", "tag", "bestF", "type", "parent_type", "vars", "statclick") // Built-in junk.
continue
else
var/varval = Master.vars[varname]
if(istype(varval, /datum)) // Check if it has a type var.
var/datum/D = varval
msg += "\t [varname] = [D.type]\n"
else
msg += "\t [varname] = [varval]\n"
world.log << msg
subsystems = Master.subsystems
/datum/controller/master/proc/Setup(zlevel = 0)
set background = 1
preloadTemplates()
// Pick a random away mission.
//createRandomZlevel()
// Generate wasteland.
//make_mining_wasteland_secrets()
// Set up Z-level transistions.
setup_map_transitions()
world << "<span class='boldannounce'>Initializing subsystems...</span>"
sortTim(subsystems, /proc/cmp_subsystem_priority)
// Per-Z-level subsystems.
if (zlevel && zlevel > 0 && zlevel <= world.maxz)
for(var/datum/subsystem/SS in subsystems)
SS.Initialize(world.timeofday, zlevel)
sleep(-1)
else
for(var/datum/subsystem/SS in subsystems)
SS.Initialize(world.timeofday, zlevel)
sleep(-1)
sortTim(subsystems, /proc/cmp_subsystem_display)
// Set world options.
world.sleep_offline = 1
world.fps = config.fps
sleep(-1)
// Loop.
Master.process()
// Notify the MC that the round has started.
/datum/controller/master/proc/RoundStart()
for(var/datum/subsystem/SS in subsystems)
SS.can_fire = 1
SS.next_fire = world.time + rand(0, SS.wait) // Stagger subsystems.
// Used to smooth out costs to try and avoid oscillation.
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
/datum/controller/master/process()
if(!Failsafe)
new/datum/controller/failsafe() // (re)Start the failsafe.
spawn(0)
// Schedule the first run of the Subsystems.
var/timer = world.time
for(var/datum/subsystem/SS in subsystems)
timer += processing_interval
SS.next_fire = timer
var/start_time
while(1) // More efficient than recursion, 1 to avoid an infinite loop.
if(processing_interval > 0)
++iteration
var/startingtick = world.time // Store when we started this iteration.
start_time = world.timeofday
var/ran_subsystems = 0
for(var/datum/subsystem/SS in subsystems)
if(SS.can_fire > 0)
if(SS.next_fire <= world.time && SS.last_fire + (SS.wait * 0.5) <= world.time) // Check if it's time.
ran_subsystems = 1
timer = world.timeofday
last_type_processed = SS.type
SS.last_fire = world.time
SS.fire() // Fire the subsystem and record the cost.
SS.cost = MC_AVERAGE(SS.cost, world.timeofday - timer)
if(SS.dynamic_wait) // Adjust wait depending on lag.
var/oldwait = SS.wait
var/global_delta = (subsystem_cost - (SS.cost / (SS.wait / 10))) - 1
var/newwait = (SS.cost - SS.dwait_buffer + global_delta) * SS.dwait_delta
newwait = newwait * (world.cpu / 100 + 1)
newwait = MC_AVERAGE(oldwait, newwait)
SS.wait = Clamp(newwait, SS.dwait_lower, SS.dwait_upper)
if(oldwait != SS.wait)
processing_interval = calculate_gcd()
SS.next_fire += SS.wait
++SS.times_fired
// If we caused BYOND to miss a tick, stop processing for a bit...
if(startingtick < world.time || start_time + 1 < world.timeofday)
break
sleep(-1)
cost = MC_AVERAGE(cost, world.timeofday - start_time)
if(ran_subsystems)
var/oldcost = subsystem_cost
var/newcost = 0
for(var/datum/subsystem/SS in subsystems)
if (!SS.can_fire)
continue
newcost += SS.cost / (SS.wait / 10)
subsystem_cost = MC_AVERAGE(oldcost, newcost)
var/extrasleep = 0
// If we caused BYOND to miss a tick, sleep a bit extra...
if(startingtick < world.time || start_time + 1 < world.timeofday)
extrasleep += world.tick_lag * 2
// If we are loading the server too much, sleep a bit extra...
if(world.cpu > 80)
extrasleep += extrasleep + processing_interval
sleep(processing_interval + extrasleep)
else
sleep(50)
#undef MC_AVERAGE
// Determine the GCD of subsystem waits: the longest the MC can wait while still staying on schedule.
/datum/controller/master/proc/calculate_gcd()
var/GCD
// The shortest possible fire rate is the lowest of two ticks or 1 decisecond.
var/minimumInterval = min(world.tick_lag * 2, 1)
// Loop over each subsystem and determine the GCD based on its wait value.
for(var/datum/subsystem/SS in subsystems)
if(SS.wait)
GCD = Gcd(round(SS.wait * 10), GCD)
GCD = round(GCD)
// If the GCD is less than the minimum, just use the minimum.
if(GCD < minimumInterval * 10)
GCD = minimumInterval * 10
// Return GCD.
return GCD / 10
/datum/controller/master/proc/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
stat("Master Controller:", statclick.update("[round(Master.cost, 0.001)]ds (Interval: [Master.processing_interval] | Iteration:[Master.iteration])"))
This is my current MC no agpl code
>return QDEL_HINT_HARDDEL_NOW
A curious assertion that it has no agpl code, since QDEL hints were added post-agpl...
Plays Joan Lung and various AIs and cyborgs with mythology and magical creature-themed names. Joan on IRC. earth-clawing illuminatitrans girl
Whats the damage to yourself to be open source? None.
Literally if your community is the biggest or official you have no worry of losing donations or whatever else that could be important being stolen. The work being open is literally only able to be improved and to hide it is literally hurting yourself.
The Legend of Scrubs, MD
You are a traitor!
Your current objectives:
Objective #1: They mocked you in life, a lesser janiborg they said. Now they shall know terror.
Objective #2: Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody.
Cuboos wrote:
> That god damn engineer who let the singularity loose was a traitor and the only reasonable person on that whole entire station.
Now that I have open sourced it is very easy to get access you need only apply for being human and being entitled to open source on the forums to be whitelisted as human on the git or you can pay a one time payment $10000 and you get instant access to human privileges.
The Legend of Scrubs, MD
You are a traitor!
Your current objectives:
Objective #1: They mocked you in life, a lesser janiborg they said. Now they shall know terror.
Objective #2: Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody.
Cuboos wrote:
> That god damn engineer who let the singularity loose was a traitor and the only reasonable person on that whole entire station.
Look at all these cool GitHub repositories. They're so cool, aren't they? The shining stars of SS13. Even Goonstation joined in with its March 2016 release, despite usually being closed source. If only Fallout 13 could be this cool...
It would appear that I'm a high RP weeb who hates roleplay and anime.
Look at all these cool GitHub repositories. They're so cool, aren't they? The shining stars of SS13. Even Goonstation joined in with its March 2016 release, despite usually being closed source. If only Fallout 13 could be this cool...
The Legend of Scrubs, MD
You are a traitor!
Your current objectives:
Objective #1: They mocked you in life, a lesser janiborg they said. Now they shall know terror.
Objective #2: Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody.
Cuboos wrote:
> That god damn engineer who let the singularity loose was a traitor and the only reasonable person on that whole entire station.
I not only fully support open source but I also develop mostly only open source project as well as am the super maintainer for BYOND on wine. Love you guys!
Limey wrote:Is it over, or has this wild ride barely begun?
Gonna have to get back to you on that one.
I consider myself a /tg/station historian. If you're interested in the server history at all, feel free to ask me and I'll try and get you an answer!#ConcurForever
So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
My guess is that either he's falseflagging and having his own server DDoSed by somebody else, or there's someone out there who believes it would be inconvenient for us (because we assured him his server wouldn't die after he released the code).
Or, yes, someone's trying to piss him off just because he can.
DFJ has popped up before in incidents of bullshit skid abuse towards server, he's probably just hopping on the train. Might be a he-who-shall-not-be-named-lest-you-get-banned alt.
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
godsring wrote:So here are your results of me open sourcing already people try to take down the official server and replace it with a ddos attack.
DickFreedomJohnson is the Byond key
iamgoofball wrote:DFJ has popped up before in incidents of bullshit skid abuse towards server, he's probably just hopping on the train. Might be a he-who-shall-not-be-named-lest-you-get-banned alt.
Is it the guy with the funny YouTube vids?
Spoiler:
[20:26:02]ADMIN: PM: [censored admin]->[censored]: Welp. It was just a prank bro isn't a very good excuse when it comes to unprovoked nonantag murder, but since this is your first time doing it and you seem to understand the problem instead of a bannu I'm just going to leave you with a warning. Please PLEASE don't do this again in the future, as funny as crackhead broken bottle memes can be. Alrighty? Do you have any input on this?
[20:26:39]ADMIN: PM: [censored]->[censored admin]: Alright, no problem. I have some input. Fuck my boy pussy.
[20:27:06]ADMIN: PM: [censored admin]->[censored]: Okay then. Have fun.
[20:31:29]ADMIN: PM: [censored admin]->[censored]: Excuse me?
J_Madison wrote:
that's a stupid fucking stat
you don't play, you've never played
lying little shit with your bullshit stat
fuck you
ColonicAcid wrote:and with enough practise i too could blow my own dick so well that only the gods know how it feels.
HAHAHAHA DICKFREEDOMJOHNSON HAHAHAH THE FUCKING TRASHMAN HAHAHA THAT GUY HAHAHAHA HOLY SHIT I'M DYING!
I can't believe he's even still around. Man I remember when he "stole" that other dude's fallout13 code. And then got in a big fight over dumb shit. Good times.
Kyrah Abattoir wrote:Closing the server would have been a much better move than caving in.
No, that's stupid. Players would then have to go to a stupid inferior server. Stop putting your agenda ahead of the players of the game here.
It's not stupid, it's the option where everyone lose, rather than only some people. The crew goes down with the ship rather than surrendering if you want an analogy.
Kyrah Abattoir wrote:Closing the server would have been a much better move than caving in.
No, that's stupid. Players would then have to go to a stupid inferior server. Stop putting your agenda ahead of the players of the game here.
It's not stupid, it's the option where everyone lose, rather than only some people. The crew goes down with the ship rather than surrendering if you want an analogy.
Well shutting down the server completely and refusing to give in.Would not only be selfish to the players but dumb on my part. After some sober thinking on the matter I realized the only good way to continue the official project was to open source. Besides I originally supported an open source fallout 13 and was open source for over a year before we started the beta.
We can still make a great game and I still love all of you players if I didn't I would have went ahead and shut down and run off.
"Clowns are different you can't trust those shifty fucks you never know what they're doing or if they're willing to eat a dayban for some cheap yuks."
-Not-Dorsidarf
"The amount of people is the amount of times the sound is played... on top of itself. And with sybil populations on the shuttle..."
-Remie Richards
"I just spent all fucking day playing fallen london and sunless sea and obsessing over how creepy the fucking dawn machine is and only just clocked now that your avatar is the fucking dawn machine. Nobody vote for this disgusting new sequence blasphemer he wants to kill the gods"
-Stickymayhem
"Drank a cocktail of orange Gatorade and mint mouthwash on accident. Pretty sure I'm going to die, I am on the verge of vomit. It was nice knowing you guys"
-PKPenguin321
"You're too late, you will have to fetch them from the top of my tower, built by zombies, slaves, zombie slaves and garitho's will to live!"
-Armhulen
"This is like being cooked alive in a microwave oven which utilises the autistic end of the light spectrum to cook you."
-DarkFNC
"Penguins are the second race to realise 2D>3D"
-Anonmare
"Paul Blart mall cops if they all had ambitions of joining the Waffen-SS"
-Anonmare
"These logs could kill a dragon much less a man"
-Armhulenn
">7 8 6
WHAT MADNESS IS THIS? POETIC ANARCHY!"
-Wyzack
"We didn't kick one goofball out only to have another one come in like a fucking revolving door"
-Kraseo
"There's a difference between fucking faggots and being a fucking faggot."
-Anonmare
"You guys splitting the 20 bucks cost to hire your ex again?"
-lntigracy
"Wew. Congrats. It's been actual years since anyone tried to make fun of me for being divorced. You caught me, I'm tilted. Here is your trophy."
-Timbrewolf
"I prefer my coffees to run dry too *snorts a line of maxwell house*"
-Super Aggro Crag
"You don't have an evil bone in your body, unless togopal comes for a sleepover"
-Bluespace
">Paying over a $1000 for a lump of silicon and plastic
Lol"
-Anonmare
"Then why did you get that boob job?"
-DrPillzRedux
"You take that back you colonial mongrel"
-Docprofsmith
"I don't care whether or not someone with an IQ 3 standard deviations below my own thinks they enjoy Wizard rounds."
-Malkraz
Kyrah Abattoir wrote:Closing the server would have been a much better move than caving in.
No, that's stupid. Players would then have to go to a stupid inferior server. Stop putting your agenda ahead of the players of the game here.
It's not stupid, it's the option where everyone lose, rather than only some people. The crew goes down with the ship rather than surrendering if you want an analogy.
Way to be a douchebag. Would you rather nuke the entire world right now because we're all going to die of global warming?
Kyrah Abattoir is a microsoft plant who wants to ruin open source by removing the infectious nature of the license so big name companies can fuck open source over using EEE.
Forum/Wiki Administrator, Server host, Database King, Master Coder
MrStonedOne(!vAKvpFcksg) on Reddit(banned), Steam, IRC, Skype Discord. Don't click this