ID:158873
 
Forgive me, but how would you save EVERYTING on a map?
Thanks.
Nice but i get: error:a.loc:cannot hcange constant value

Great code here because it's so accessible, and has a few neat tricks (such as using world.Del() to automatically save on world down) too.

I'm not saying the code is perfect, but it's a good framework to start to grok how saving/loading works in relation to the world. Once a coder gets that down pat, they can move on to doing things like removing an additional x/y/z variable on each object and turf (because that's a ton of memory bloat) and so on.
In response to Geldonyetich
Eh, I wouldn't call code that not only is unclean, but wouldn't even work 'great'. Code shouldn't be primarily fed in response to a question anyway.
In response to Kaioken
I mostly commended it on the grounds it's just the right level for a newbie to pick at. It's not so very advanced as to confuse them with the added complication involved in doing it cleanly. That it didn't work was almost a point in its favor: okay, understanding what one can see here, can you guess how to fix it? ;)
In response to Geldonyetich
But the code doesn't even work, so everything you say about it is invalid. The guy obvisiously doesn't know what he's doing.
In response to T3h P3ngu1n
T3h P3ngu1n wrote:
But the code doesn't even work, so everything you say about it is invalid. The guy obvisiously doesn't know what he's doing.

Ah, but that goes back to my very first post where I get into "I'm not saying the code is perfect."

There's a certain level of what you can learn even in that which is so very imperfect as to not work. The thing is, if your goal is to learn, having the answer handed to you correct on the very first try leaves no journey from which to profit.

The subtlety of the method behind my madness is oft missed, or else confused for simple trolling.
Horrible mess and has a ton of bloat. You're making this whole thing so much worse (and more complicated) than it needs to be.

proc
save_world()
var/list/turfs = list()
for(var/turf/T)
turfs += T
var/savefile/F = new("world.soicanjustwriteanythinghereanditshowsuponthescreen")
F << turfs

load_world()
new("world.soicanjustwriteanythinghereanditshowsuponthescreen")
var/list/L
F >> L


Flexibility sacrificed in the name of simplicity.

This does save every mob, including players, which is going to play silly buggers with things. But, that's for you to deal with. Here's a hint: use mob/Read() to delete the mob before anything is loaded, if it's being loaded from the world savefile. You can't really get around the mob being saved in the first place, unfortunately.

Oh, also: if you're loading while the world's running, all the mobs will be bumped to nowhere. So you might not want to do that.
In response to Garthor
Garthor wrote:
Here's a hint: use mob/Read() to delete the mob before anything is loaded

You can also override mob/Write() to prevent saving [player] mobs [when they're not supposed to be].

You can't really get around the mob being saved in the first place, unfortunately.

Of course you can, with simple "tricks" in atom (or turf)/Write(). Here's a quick example of one method that prevents turfs from being saved with the mobs on them.
turf/Write(savefile/F)
var/list/mobs = new
for(var/mob/M in src)
mobs += M
src.contents -= M
..() //do the saving, now without any mobs in contents
src.contents += mobs //return the mobs that were removed
In response to Kaioken
Kaioken wrote:
Garthor wrote:
Here's a hint: use mob/Read() to delete the mob before anything is loaded

You can also override mob/Write() to prevent saving [player] mobs [when they're not supposed to be].

mob/Write() is called AFTER the contents of the turf have been written. If you stop it there it'll still create an empty /mob.

You can't really get around the mob being saved in the first place, unfortunately.

Of course you can, with simple "tricks" in atom (or turf)/Write(). Here's a quick example of one method that prevents turfs from being saved with the mobs on them.
> turf/Write(savefile/F)
> var/list/mobs = new
> for(var/mob/M in src)
> mobs += M
> src.contents -= M
> ..() //do the saving, now without any mobs in contents
> src.contents += mobs //return the mobs that were removed


Well, besides that. I think it's rather clumsy, and has the potential to screw around with things (though I can't think of an example off-hand).
In response to Garthor
It seems you really underestimate what can be done with BYOND's savefile control and object saving procs...?

Garthor wrote:
mob/Write() is called AFTER the contents of the turf have been written.

Huh? No, Write() is the proc that's called to save objects and their vars. When you call the built-in function of it / ..(), THEN it saves the vars.

If you stop it there it'll still create an empty /mob.

(Which you should be able to get rid of)

Well, besides that.

Another method would be to edit the stored value of contents after it's already saved.
turf/Write(savefile/F)
..() //do the saving
var/saved_contents
F["contents"] >> saved_contents
//modify saved_contents in any way you want...
F["contents"] << saved_contents //overwrite with the changed var
//-------------------------
//if you want to just not save the contents and use \
the default value for it, you can just do

F.dir -= "contents


I think it's rather clumsy, and has the potential to screw around with things.

It doesn't have potential to screw with anything as-is, only if the programmer of the project adds parts in parent-level Write()s that might be affected. Otherwise, the contents is restored immediately following, so it's invisible to the rest of the game, since there's no sleep() or anything like that.
In response to Kaioken
Another method would be to edit the stored value of contents after it's already saved.

That results in a cross-reference error, and the file output silently fails. I don't know EXACTLY what happens, but if it tries to override an object reference with a new reference to to the same object in a savefile, it just halts. If you were to save it into another dir, like "content", you'd get "content = list(object("../contents/.0")), so if it's trying to override contents with that it's understandable why it wouldn't work. You'd have to rewrite the entire Write() proc to keep it from ever writing contents.

Moving mobs off turfs and back onto them is likely to be the best solution if you totally refuse to allow a few extra lines to be written to a savefile. It's not likely to cause problems, but a proc like this is likely to end up being made a background proc, which means it can sleep unexpectedly. I think it only does that at the end of procs / iterations of a loop, but because turf/Write() will be calling obj/Write(), there could be a sleep in there.

However, I think you just need to realize that this is all excessive and inefficient. Just not loading the mobs is so much easier.
In response to Garthor
Garthor wrote:
That results in a cross-reference error, and the file output silently fails.

I'll look into it sometime, there's most likely a way to fix that. Though if replacing the contents directly is problematic, you can always remove it from the savefiles first, then new contents.

but a proc like this is likely to end up being made a background proc

Write()? xD Maybe the general loop that saves all the turfs, but not this proc (would be silly and so not likely) - so it isn't problematic. Actually, it wouldn't have been either way; something isn't inherently bad if you do something to break it, and it breaks. Just don't break it in the first place. Of course, a background proc shouldn't be automatically sleeping at all if there's no loop, too.

However, I think you just need to realize that this is all excessive and inefficient. Just not loading the mobs is so much easier.

Both ways are as easy; there's also no point in saving excess data if it's useless and you won't be loading it, and also needlessly wastes space.
In response to Kaioken
Kaioken wrote:
Garthor wrote:
That results in a cross-reference error, and the file output silently fails.

I'll look into it sometime, there's most likely a way to fix that. Though if replacing the contents directly is problematic, you can always remove it from the savefiles first, then new contents.

Tried it. Same issue.

but a proc like this is likely to end up being made a background proc

Write()? xD Maybe the general loop that saves all the turfs, but not this proc (would be silly and so not likely) - so it isn't problematic. Actually, it wouldn't have been either way; something isn't inherently bad if you do something to break it, and it breaks. Just don't break it in the first place. Of course, a background proc shouldn't be automatically sleeping at all if there's no loop, too.

Whoops, you're right. Re-read the background setting and it wouldn't result in Write() being set to background.

However, I think you just need to realize that this is all excessive and inefficient. Just not loading the mobs is so much easier.

Both ways are as easy; there's also no point in saving excess data if it's useless and you won't be loading it, and also needlessly wastes space.

The issue is, like I said, that you end up doing MORE work to prevent it from using that space. And besides, space is cheap, processing power is what you have to worry about.

If it makes you happy, you can override mob/Write() like so:

mob
Write()
if(cd == "/.0")
..()


There, now all that gets written is:

contents = list(object(".0"))
.0
type = /mob


A whopping 86 bytes. Only 54 if there's already something in the turf's contents. Oh, I guess a few more bytes if you have a longer type path. If you have REALLY REALLY LONG type paths it might double that.

Though, if you don't do this it does technically give you backup data for players, if you're willing to dive for it. But that's generally something you'd think about after you need it, not before.
In response to Garthor
Garthor wrote:
Tried it. Same issue.

Actually, I've tried the original code I've posted in a testing environment and it worked fine for me, no weird unaccountable error popped up.
(Used this testing code:)
turf/Write(savefile/F)
..() //do the saving
var/saved_contents
F["contents"] >> saved_contents
for(var/mob/M in saved_contents)
saved_contents -= M
F["contents"] << saved_contents //overwrite with the changed var

mob/verb
NewMob()
set category = "turfsav"
new/mob(loc)
NewObj()
set category = "turfsav"
new/obj(loc)
Save_Reload_Turf(turf/T in view())
set category = "turfsav"
fdel("test.sav")
var/savefile/F = new("test.sav")
T.icon_state = "water"
F << T
T.icon_state = "grass"
alert("reload")
F >> T
Save_Reload_Turf2(turf/T in view())
set category = "turfsav"
fdel("test.sav")
var/savefile/F = new("test.sav")
T.icon_state = "water"
T.Write(F)
T.icon_state = "grass"
alert("reload")
T.Read(F)

Couldn't manage to get the error you've mentioned with any experimenting with those verbs; I've also tried both a temporary savefile and one saved to disk. Most likely something in the project you've used to test it made it screw up; as we've discussed, another Write() override could do this. Anyway, you should test these things in a mostly empty/stripped project so nothing interferes.

The issue is, like I said, that you end up doing MORE work to prevent it from using that space.

How is it an issue? This is very small extra work (that probably takes less than half the time it took to write any of the posts we've both made here), and doing that is normal; programmers do more work in order to add benefits all the time, even small ones.

And besides, space is cheap, processing power is what you have to worry about.

Space isn't unimportant, and there are more benefits to saving space other than having the file take up less physical space on disk. Of course, my main point was to show you there are multiple ways to prevent the mob from being saved at all; you don't have to agree with me on whether you should save mobs or not if you never load them. Leaving it saving mobs as-is seems like just the needlessly-lazy way to me, but we can agree to disagree.
In response to Kaioken
Your solution here creates the exact problem you were attempting to solve: you're loading mobs from the savefile and creating copies of them all over the place.

Aside from that, it's also considerably slower. It's taking around 10%-20% longer to write to the savefile, read from the savefile, loop through a list, and then write to the savefile again for EVERY SINGLE TURF. And you aren't even saving any memory! You're writing to contents even if there are no contents, which is bloating your savefile if the majority of turfs are empty. Or, that's an overestimation: if there are more empty turfs than mobs, it's wasting space.

This isn't an "agree to disagree" situation. This is one where your position is wrong and you need to accept that. Saving the mobs isn't "needlessly lazy", it's done because the alternative is WORSE.
In response to Garthor
Garthor wrote:
This isn't an "agree to disagree" situation.

Maybe, maybe not, but I don't wish to continue arguing the same argument with you ad infinitum, so at this point I shall agree to disagree with you. ;)

This is one where your position is wrong and you need to accept that. Saving the mobs isn't "needlessly lazy", it's done because the alternative is WORSE.

It isn't necessarily. It can be done differently than the specific examples I've posted; like almost anything, the process isn't set in stone and you can tweak and alter it, thus avoiding the problems you've described.
In response to Kaioken
Kaioken wrote:
It isn't necessarily. It can be done differently than the specific examples I've posted; like almost anything, the process isn't set in stone and you can tweak and alter it, thus avoiding the problems you've described.

Aside from rewriting the Write() proc entirely so that it's entirely in DM code, I don't see how. And if you did that then it would still be slower. How about providing an actual, working example rather than insisting on its existence?

Insisting that you're right when you're unable to prove that you're right is INCREDIBLY intellectually dishonest, and you need to start thinking about the nature of reality here: would you rather "lose an argument" or be literally delusional?
In response to Garthor
Garthor wrote:
Aside from rewriting the Write() proc entirely so that it's entirely in DM code, I don't see how.

Not a problem; originally, you didn't see how preventing mobs from being saved was at all possible, and now you've apparently forgotten that example again. I shouldn't have to give complete, finalized examples of all the possible implementations, nor do I have the time and patience to.

How about providing an actual, working example rather than insisting on its existence?

I've already given multiple ones, even though to one you've replied claiming it produces bogus errors I couldn't even reproduce, and one you've said "potentially causes problems if you do X which could break it" (as if it doesn't apply to anything). Also, read above.

Insisting that you're right when you're unable to prove that you're right is INCREDIBLY intellectually dishonest, and you need to start thinking about the nature of reality here: would you rather "lose an argument" or be literally delusional?

Indeed, so you should probably start thinking. =)
Page: 1 2