During some code changes to the goonstation fork of SS13 codebase, it became apparent to me that I was trying to reference "config" values in the New() call of an obj placed on the map (well, technically the obj was creating a datum which was calling a proc which was referencing the config values but that's neither here nor there...). It soon became apparent however that the reason I couldn't reference these config values was because they were read from a file in a proc called by world/New(), which isn't called until AFTER the map has loaded all objects.
My suggestion is a new proc that gets called before this map creation process, essentially making it the first "point of entry" for games. Ideally config...stuff would go in there and would therefore be available to ~everything ever~ which would be rather handy.
Existing workarounds (ways to accomplish this without a new proc): three come to mind: obj/New() override with a global var to limit to first run, special 1x1 area on coords 1,1,1 that is called first during map creation, map spawner objects that "create" the desired object on the map AFTER world/New is called. Now, these all technically work but are either ugly gross hacks, a pain in the ass and/or have the potential for performance drawbacks.
Potential issues (involved with the introduction of a new proc): considering the world wont be initialized yet, things like world.Export() and so on wont be available. I have no real suggestion regarding this issue.
1
2
ID:1933625
Sep 10 2015, 8:57 am (Edited on Sep 10 2015, 2:06 pm)
|
|||||||
| |||||||
Kats, he wants there to be some kind of initialization that happens before any of the objects on the map. client.New() and its user mob creation aren't called until the world initializes, but any objects on the map have their New() called before world.New().
|
I appreciate that I may not have been as detailed as required but also you appear to have barely read my post before farting out a reply so let me clarify.
I'm trying to set up config variables for use by OBJECTS (not clients or mobs) in their New(). As described, objects places on the map call their New() BEFORE world does, meaning any config setup placed in world/New() isn't called for aforementioned objects. In addition, config setup may not be the ONLY use of the new proc I proposed, it is simply an example that fits my current use-case. I imagine other coders could think of many things that could go there. |
/datum/configuration/config I think you could get around this by using the /datum/configuration/config = new() in an arbitrary file syntax, although don't quote me on if that gets created before or after the map. |
In response to MisterPerson
|
|
MisterPerson wrote:
I think you could get around this... Yes, there's several ways to get around this, what we're requesting here is a proper hook for this in DM instead of having to make ways around it. |
Datum initialization is currently the only way around this.
I think a world.Initialize() proc could be of use. |
Thank you MisterPerson, that accurately describes what I'm getting at. In that code block example, "damage" will be null or result in a runtime as config doesn't exist yet.
Kats, this isn't about SS13 really. It's a basic core aspect of the way byond initially loads a server. I appreciate that SS13 has a mostly terrible codebase however this is irrelevant in this discussion. |
I ran into this a while back when trying to keep global lists initialized in world/New() (taking Lummox's advice there), but ended up ditching that once I realized the order in which things were loaded.
Supported. |
I could see some use out of a feature like this, but overall I've never had a problem with the order of initialization and even if I thought I would, I'd end up just writing an init function separate from new to be called once the world was fully initialized.
|
But...the whole point of this is to call stuff BEFORE the world is initialized...
|
In response to Wirewraith
|
|
Wirewraith wrote:
But...the whole point of this is to call stuff BEFORE the world is initialized... But my point is that it's not strictly necessary to do it before the world loads up. Waiting for the world to finish loading before trying to initialize everything is a far more secure way of handling startup. There's very few benefits to magically calling functions before the world starts. Trying to get references initialized before the world has time to create those objects to be referenced is why this discussion was started in the first place. |
But myself (and others) have mentioned that it WOULD be useful to init some stuff before the map objects load. Stuff like config for example. I'm not sure what's more "secure" about leaving it to world/New or what would be "magical" about calling procs from this hypothetical new proc.
The references I'm trying to access in my use case (a config datum, populated by reading a file) are distinct from the objects created during map loading. I'm not...trying to reference an actual object on the map before the map is fully loaded or anything. |
In response to Wirewraith
|
|
Okay, so let me see if I understand you correctly.. You're trying to setup datum variables and the like before the map loads so when they do begin loading, they can use that data in their own construction? For things such as configuration settings and whatnot, right?
|
Correct, I think. Unless you think the datum is somehow being setup on map load as well which would be false.
Further clarification: the datum variables would be used in separate object constructors, not for...itself. |
Now I understand what you're talking about. To me, it sounded like an arbitrary designation of creating certain objects before others in instances where it was not necessary. "Config files" is a broad and vague term that can mean a lot of things.
I know of ways that aren't hacky of emulating this behavior, but as many have suggested, this would be the simplest solution. My solution would be having a file handler built into the atom/New() function that checked if the config file had been loaded yet, if not, it would load it. It would check the file every time an atom was created, but it would only ever actually load the file once. Overall, there would be basically no performance hit for very minimal effort involved. Or the other solution I mentioned of simply creating an init() function to delay the loading of the data until after the file has been loaded. It would require a for(atom/a in world) call, though, which is the only downside. Regardless of the workarounds, a built in init function would be useful. |
We don't need more and more hacks in DM, its already getting kinda gross. It wouldn't be hard to add a quick solution for this and it'd be really handy in the long run.
|
Well, I think this introduces a bit of a predicament. A world/Init wouldn't entirely make much sense, because the /world itself hasn't been initialized yet.
What could be kind of interesting, though, is some kind of /instance type or configurable (by similar means of world/mob and world/hub and the like) type, an instance of which gets created pre-Init and gets destroyed in the event of a clean shutdown. Could be expandable in the future for more interesting things, I suspect. |
I didn't actually say to make it world/Init. I don't especially care what it's called, just when it happens.
|
In response to Wirewraith
|
|
Wirewraith wrote:
I didn't actually say to make it world/Init. I don't especially care what it's called, just when it happens. Yeah, I read your post and took it as inspiration. I think it could lead to some interesting things, if there was a concept of an Init datum that influenced world break down and startup at a...different level. |
1
2
Client and mob New() functions aren't called until after the world.New() function concludes. I'm not exactly sure the problem you're having because your description is extremely vague. What exactly are you trying to do that the above code can't accomplish?