[WIPz] CBash (Alpha)

Post » Wed Sep 01, 2010 5:34 pm

Hrm. v1.72? Same as the one I tested that function on. I really don't know what's going on there.

As for the new bug report, I'm not surprised. Should get that fixed in the next update.
User avatar
Steeeph
 
Posts: 3443
Joined: Wed Apr 04, 2007 8:28 am

Post » Wed Sep 01, 2010 12:16 pm

Bashed a good 230 mods with svn rev 488. Great job! Everything looks good! With CBash, the bashing procedure is about 20x faster (2 minutes instead of 40)!
User avatar
dav
 
Posts: 3338
Joined: Mon Jul 30, 2007 3:46 pm

Post » Wed Sep 01, 2010 10:20 am

Hi,

Trying CBash with WryeBash 285. I think I've got the correct versions of Python and ComTypes (from WryeBash requirement post) and the latest CBash from sourceforge. I am using Win XP x64 with x86 versions of Python and ComTypes.

On building a BashPatch I get:

Traceback (most recent call last):
File "G:\Oblivion Utilities\Wrye Bash\Mopy\basher.py", line 4921, in Execute
raise
File "G:\Oblivion Utilities\Wrye Bash\Mopy\basher.py", line 4880, in Execute
patchFile.initData(SubProgress(progress,0,0.1)) #try to speed this up!
File "G:\Oblivion Utilities\Wrye Bash\Mopy\bosh.py", line 14262, in initData
patcher.initData(SubProgress(progress,index))
File "G:\Oblivion Utilities\Wrye Bash\Mopy\bosh.py", line 16477, in initData
fullNames.readFromMod(srcInfo)
File "G:\Oblivion Utilities\Wrye Bash\Mopy\bosh.py", line 12191, in readFromMod
for type,block in modFile.aggregates.iteritems():
File "G:\Oblivion Utilities\Wrye Bash\Mopy\cint.py", line 17247, in aggregates
return dict((("GMST", self.GMST),("GLOB", self.GLOB),("CLAS", self.CLAS),("FACT", self.FACT),
File "G:\Oblivion Utilities\Wrye Bash\Mopy\cint.py", line 16701, in GMST
CBash.GetGMSTs(self._CollectionIndex, self._ModName, cRecords)
File "C:\Program Files (x86)\Common Files\Python26\lib\ctypes\__init__.py", line 366, in __getattr__
func = self.__getitem__(name)
File "C:\Program Files (x86)\Common Files\Python26\lib\ctypes\__init__.py", line 371, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'GetGMSTs' not found

Regards,
niche99
User avatar
Sabrina Schwarz
 
Posts: 3538
Joined: Fri Jul 14, 2006 10:02 am

Post » Wed Sep 01, 2010 11:44 pm

The latest CBash on sourceforge requires the latest http://sourceforge.net/projects/oblivionworks/ of Bash. As you've seen, you can't use it on 285.
User avatar
noa zarfati
 
Posts: 3410
Joined: Sun Apr 15, 2007 5:54 am

Post » Wed Sep 01, 2010 10:46 pm

The latest CBash on sourceforge requires the latest http://sourceforge.net/projects/oblivionworks/ of Bash. As you've seen, you can't use it on 285.


Thanks Waruddar.
User avatar
Antony Holdsworth
 
Posts: 3387
Joined: Tue May 29, 2007 4:50 am

Post » Wed Sep 01, 2010 7:26 pm

So, I've recently started playing with Oblivion again, and I'm pretty frustrated with the patch times in bash. So, I've been looking into starting using CBash to try and rectify things. From what I gather, the SVN version of CBash is the best, and it requires the SVN version of Bash to work. That's fine and all, since I know how to use SVN, but I was wondering if I could get a comment from somebody using both of those on how stable they are?

I'm a bit nervous about using the SVN branch of bash in particular...
User avatar
Mimi BC
 
Posts: 3282
Joined: Sat Oct 07, 2006 10:30 pm

Post » Wed Sep 01, 2010 5:22 pm

So, I've recently started playing with Oblivion again, and I'm pretty frustrated with the patch times in bash. So, I've been looking into starting using CBash to try and rectify things. From what I gather, the SVN version of CBash is the best, and it requires the SVN version of Bash to work. That's fine and all, since I know how to use SVN, but I was wondering if I could get a comment from somebody using both of those on how stable they are?

I'm a bit nervous about using the SVN branch of bash in particular...

That info was from July - when Wrye Bash was v.285

Wrye Bash 291 is almost released - first time with installer. And cbash has been included in the Wrye Bash package for a few versions now.
User avatar
Markie Mark
 
Posts: 3420
Joined: Tue Dec 04, 2007 7:24 am

Post » Wed Sep 01, 2010 11:52 am

Oh wow, guess I'm a bit behind the times!

Is that to say that CBash is already in use, and it's STILL this slow? Or do I need to rename something to enable it?
User avatar
Sunnii Bebiieh
 
Posts: 3454
Joined: Wed Apr 11, 2007 7:57 pm

Post » Wed Sep 01, 2010 11:17 pm

Don't you need to rename "Rename_CBash.dll" to "CBash.dll" to get it working? I'd assume that's what you're looking for.
User avatar
Cartoon
 
Posts: 3350
Joined: Mon Jun 25, 2007 4:31 pm

Post » Wed Sep 01, 2010 1:34 pm

I saw that, but wasn't sure if it was that, or something specifically to deal with mod renaming. Lol, now I know.

I'm running it right now. It seems so much faster, but is producing a rather frightening list of output to the wxpython stdout/stderr window. Hopefully, that's just logging text that belongs there. Guess I'll know if it worked soon! Thanks for all the help guys!
User avatar
Flutterby
 
Posts: 3379
Joined: Mon Sep 25, 2006 11:28 am

Post » Wed Sep 01, 2010 7:42 pm

Guys so what's the status of Cbash now? Is it considered stable/safe to use?

Speeding up BAIN's refreshing of my fat data folder would be very nice.. Unless it messes up things in the tradeoff :)
User avatar
Chris BEvan
 
Posts: 3359
Joined: Mon Jul 02, 2007 4:40 pm

Post » Wed Sep 01, 2010 8:20 pm

In general, the latest stable version of CBash will be included with Bash.

The SVN release of CBash is not guaranteed to be stable (though it often is). Right now though, the SVN release of CBash is not stable. I'm refactoring most of the code so that I can start adding support for FO3 and FNV, and I haven't done any testing on the latest changes.

The CBash build included with Bash is an older build from before the refactoring and is mostly safe to use. However, I can't recommend its general use atm due to a few bugs that Arthmoor reported. I have not been able to reproduce the bugs on my end, but they managed to break his Bashed Patch. Right now I don't know if these bugs are in CBash or if they're in how Bash is using CBash. I will be tackling these bugs once the refactoring is done and before I start on FO3 / FNV support. I should get to it within a week's time.

Btw, all CBash does is load/edit esp and esm files, so it will do nothing for BAIN. When used by Bash, it does make the Bashed Patch process quite a bit faster though (from ~40 minutes to ~1.5 minutes in one test case). As well, you don't have to use Bash to use CBash.
User avatar
Marina Leigh
 
Posts: 3339
Joined: Wed Jun 21, 2006 7:59 pm

Post » Wed Sep 01, 2010 7:06 pm

The other big thing with CBash is being able to merge patches though. I have requested new Bash tags that will allow certain patches to be imported, but if those don't get added, then I might be looking at CBash to merge them instead. Basically I need to create a whole bunch of patches for Oblivion XP and people with large mod lists aren't going to be able to use them unless they can be imported or merged into the Bash patch.

So I guess at this point, I'm keeping an eye on WB and CBash to see who gets there first :)
User avatar
Dan Endacott
 
Posts: 3419
Joined: Fri Jul 06, 2007 9:12 am

Post » Wed Sep 01, 2010 11:20 am

@Waruddar Thanks for the update and explanation.. And damn 40 to 1 is not a bit faster.. It's just freakin'impressive :)
I'll be waiting for a new stable release fully working with WB!

@Andalaybay Great to know you're tackling the quests'uberpatch for XP!
I can't start (finally) playing for real without that. :)
User avatar
Danny Blight
 
Posts: 3400
Joined: Wed Jun 27, 2007 11:30 am

Post » Wed Sep 01, 2010 5:21 pm

andalaybay, it depends on what exactly you're needing. I've been avoiding the Bash thread recently (so I can concentrate on CBash), so I don't know anything about your request. Feel free to elaborate on it in this thread or in a pm.

The main reason I will add something to CBash is if the requested functionality is generic. If Bash is the only possible user of the function, I'll suggest that it be placed in Bash (or more likely, add it to Bash myself).

Technically, there's not much that Bash with CBash can do that Bash without CBash can't already do on its own (eventually). CBash essentially replaces Bash's (slow) mod handling abilities with it's (fast) mod handling abilities. The main benefit to Bash (other than speed...I have mentioned speed, yes?) is that more information is available when creating a bashed patch.

This extra information does let Bash with CBash do a few things that Bash without CBash can't. Off the top of my head, the undeletion of records is a prime example.

The following goes a little off-topic, but may be of interest to those wanting to know how Bash differs when creating a bashed patch on its own vs. when it uses CBash:

When Bash makes a bashed patch on its own, it's goes through the mods one at a time in order. It looks at a mod, checks each record to see if it might need to do something, and adds it to the bashed patch if it might (replacing any existing record in the patch), and then goes to the next mod. Once Bash has gone to the next mod, it remembers nothing from the mod before. All it looks at is the current mod. It doesn't even know what's been copied to the Bashed Patch until it processes it at the very end and discards any records that weren't actually needed.

This is the main reason why Bash doesn't have the same undelete function that TES4Edit has. By the time Bash comes across a deleted record, it has already forgotten about everything that came before. So it can't fill in the missing information on the deleted record unless a later loading mod happens to override the deleted record. TES4Edit does know about every record that came before, so it can easily fill in that missing information.

With CBash on the other hand, Bash goes through each winning record one at a time, and has access to every conflicting record. So it suddenly becomes possible to do things such as properly undeleting records (which is one of the functions on my to-do list).
User avatar
Kortknee Bell
 
Posts: 3345
Joined: Tue Jan 30, 2007 5:05 pm

Post » Wed Sep 01, 2010 3:46 pm

Traceback (most recent call last):  File "C:\Games\Oblivion\Mopy\basher.py", line 5021, in Execute    raise  File "C:\Games\Oblivion\Mopy\basher.py", line 4975, in Execute    patchFile.buildPatch(SubProgress(progress,0.1,0.9)) #try to speed this up!  File "C:\Games\Oblivion\Mopy\bosh.py", line 15628, in buildPatch    patcher(self, subProgress)  File "C:\Games\Oblivion\Mopy\bosh.py", line 27854, in finishPatch    argonianEyeMeshes = eye_meshes[self.argonianEye]KeyError: (bolt.Path('Oblivion.esm'), 256286) 

How can I fix this
I am using wrye bash 290 is there another update for cbash?
User avatar
Dawn Farrell
 
Posts: 3522
Joined: Thu Aug 23, 2007 9:02 am

Post » Wed Sep 01, 2010 10:15 am

I'm in the middle of testing an update for CBash, but it isn't ready yet. Unfortunately, the next release won't fix your problem because that's actually a bug in Bash (and should be brought up in that thread).

Since Bash uses CBash, it can be difficult to tell which program is responsible. Typically though, if you get an error message like that it's a problem with Bash. If CBash is messing up, you're more likely to either see the entire program crash or find out that your Bashed Patch is corrupted.

Your problem is a reoccurring one that the Bash team hasn't quite pinned down. It can occur regardless of whether you have CBash enabled or not. For whatever reason, Bash is unable to locate the argonian eye record. It really shouldn't happen unless you've somehow modified Oblivion.esm (it may occur if you're using Nehrim, but I don't know for sure). My only advice is to try using Bash without CBash enabled, and see if that happens to help.

Actually, CBash shouldn't be used at all right now unless you're testing it and verifying the resulting patch in TES4Edit. While it works 99% of the time, there are a few remaining bugs that are preventing me from recommending it for general use. The next CBash update will address those issues.
User avatar
Marcus Jordan
 
Posts: 3474
Joined: Fri Jun 29, 2007 1:16 am

Post » Wed Sep 01, 2010 12:46 pm

andalaybay, it depends on what exactly you're needing. I've been avoiding the Bash thread recently (so I can concentrate on CBash), so I don't know anything about your request. Feel free to elaborate on it in this thread or in a pm.
... snipped ...


My understanding is that CBash already does what I need, it's just a matter of it stabilizing enough for everybody to use. My main concern is that I'm already having enough problems getting people to install Oblivion XP properly, let alone telling them to rename a dll so that Wrye Bash runs in the correct mode. I also don't think all Ob XP users even use WB, although if they are at the point where they can't run another plugin because they have already hit the limit, then one hopes that running WB is not an issue :wink_smile:

The patches that I need to create will consist of one quest that's enabled at game start with a script attached. The patch will probably be completely independent of the quest mod that I'm patching and Oblivion XP by copious use of RunScriptLine. I don't have to make it independent, but doing it that way does have its merits. Now from what I understand of how CBash works, I could merge this patch with the Bash patch so that the quest and script are added to the Bash patch. Wrye Bash itself can't do this. However, PacificMorrowind felt that some new WB tags would allow WB to import the quest and script into the Bash patch.

So, at this point, I don't know which is the better route. From a users' point of view, I imagine it would be about equal once CBash is ready for wide-spread use - especially if they didn't have to worry about renaming files. Which do you think would be the better route? I am a little concerned about some of the stresses recent versions of WB seem to be experiencing...
User avatar
David John Hunter
 
Posts: 3376
Joined: Sun May 13, 2007 8:24 am

Post » Wed Sep 01, 2010 10:18 am

So basically you're wanting to have all the patches merged into the Bashed Patch, but each patch has new records (a quest and script) so Wrye Bash doesn't allow them to be merged.

Hrm. CBash can do this easily (just a matter of copying records), but it's more something Bash should handle. Bash can already do this (with or without CBash), but doesn't for one main reason: the formID of every new record in the patch would change whenever a mod is added or removed and the patch is rebuilt. This can be extremely dangerous to a player's save game.

For items and such, this would result in the player losing them every time the load order changes.

For placed npcs and creatures, it could cause them to resurrect every time the load order changes.

For quests and scripts, this would result in the quest running as if it had never run previously and all the script variables would reset. If the quest and script were designed with this in mind, it could be done safely. If they weren't, then the game could explode.

I can think of a couple solutions:
1) Wait till the tags are added to Bash. It isn't hard to allow Bash to merge new records, but it is hard to make sure it's done safely. It may require that the patch mod inject the new records into the mod it's patching.
2) If you'd rather it work now, simply make your patches override existing records rather than creating new ones. You could just override an existing quest and script in the mod you're patching...as long as the patched quest / script do the mod's original thing as well as your thing, you'd be good.

Edit: When CBash is ready for prime-time, it will be enabled by default in Bash. So there won't be any renaming business to worry about.
User avatar
kirsty joanne hines
 
Posts: 3361
Joined: Fri Aug 18, 2006 10:06 am

Post » Wed Sep 01, 2010 2:51 pm

So basically you're wanting to have all the patches merged into the Bashed Patch, but each patch has new records (a quest and script) so Wrye Bash doesn't allow them to be merged.

Hrm. CBash can do this easily (just a matter of copying records), but it's more something Bash should handle. Bash can already do this (with or without CBash), but doesn't for one main reason: the formID of every new record in the patch would change whenever a mod is added or removed and the patch is rebuilt. This can be extremely dangerous to a player's save game.

For items and such, this would result in the player losing them every time the load order changes.

For placed npcs and creatures, it could cause them to resurrect every time the load order changes.

For quests and scripts, this would result in the quest running as if it had never run previously and all the script variables would reset. If the quest and script were designed with this in mind, it could be done safely. If they weren't, then the game could explode.

I can think of a couple solutions:
1) Wait till the tags are added to Bash. It isn't hard to allow Bash to merge new records, but it is hard to make sure it's done safely. It may require that the patch mod inject the new records into the mod it's patching.
2) If you'd rather it work now, simply make your patches override existing records rather than creating new ones. You could just override an existing quest and script in the mod you're patching...as long as the patched quest / script do the mod's original thing as well as your thing, you'd be good.

Edit: When CBash is ready for prime-time, it will be enabled by default in Bash. So there won't be any renaming business to worry about.


Thanks for the insight! I was aware of form ID's changing - you see it all the time, but I didn't realize the real consequences of this in the context of my situation. I don't have to worry about items or creatures, however I do need some persistence with my variables. Otherwise, players would keep earning experience points for the quests they have completed :) I don't really have any records that I could overwrite in the mods I'm patching. I might be able to override the quests or quest scripts (provided the mods I'm patching have quest scripts), but the amount of work involved would give me nightmares!!

Just to give a bit of context, here's a snippet of the code from the patch for A Brotherhood Renewed:
begin gamemode	; make sure Oblivion XP and BrotherhoodRenewed are loaded	if ( isModLoaded "Oblivion XP.esp" && isModLoaded "BrotherhoodRenewed.esp" )		runScriptLine "set ObXPABRRewardQuest.AnvilSancDone to getStageDone aaaDBAnvilSanc 100"		if ( AnvilSancDone && AnvilPts == 0 )			runScriptLine "set ObXPMain.interOpGainedXPMessage to sv_Construct %qCompleted Reclaiming the Anvil Sanctuary%q"			runScriptLine "set ObXpMain.interOpGainedXP to 100"			Set AnvilPts to 1			Return		endif		runScriptLine "set ObXPABRRewardQuest.BravilSancDone to getStageDone aaaDBBravilSanc 100"		if ( BravilSancDone && BravilPts == 0 )			runScriptLine "set ObXPMain.interOpGainedXPMessage to sv_Construct %qCompleted Reclaiming the Bravil Sanctuary%q"			runScriptLine "set ObXpMain.interOpGainedXP to 100"			Set BravilPts to 1			Return		endif...


Using RunScriptLine so that this doesn't depend on ABR or Oblivion XP. Checking to see if the quest is done and then awarding points. This will work retroactively, so the player can load the patch after doing the quests and still get the points, but I only want to do that once, so I need persistance between game saves. I could override the quests, but that would be a lot of work and I would also have to keep updating the patch every time Arthmoor did an update to ABR. Now Arthmoor isn't as bad as TheNiceOne for frequent updates, but still... :wink_smile:

So I will wait and see what WB can do. Thanks again for the info!
User avatar
Queen of Spades
 
Posts: 3383
Joined: Fri Dec 08, 2006 12:06 pm

Post » Wed Sep 01, 2010 1:22 pm

You do have some options to preserve the variables even if the script gets reset:

1) Get/SetModLocalData should work. At the start of the script, use GetModLocalData to populate the persistent script variables. Whenever you change a variable that needs to be persistent, use SetModLocalData. This *may* cause bloating though...the data will probably stick around even if the bashed patch is rebuilt without your patches. Then again, that may be desirable.
2) Store all your variables in Oblivion XP.esp. A stringmap would work nicely...whenever a patch script is run for the first time, check the array to see if there are any stored values. Whenever you set a variable, be sure to also update the stringmap. The data will stick around until Oblivion XP.esp itself is removed (which is probably ideal).
3) I think Pluggy has the ability to read/write text files, so you could store the data in there instead. Kinda overkill though.

Basically, just store all your persistent variables somewhere that won't get reset. You'd still have to wait on Bash to add the tag, but it is doable.
User avatar
Darren
 
Posts: 3354
Joined: Wed Jun 06, 2007 2:33 pm

Post » Wed Sep 01, 2010 5:50 pm

You do have some options to preserve the variables even if the script gets reset:

1) Get/SetModLocalData should work. At the start of the script, use GetModLocalData to populate the persistent script variables. Whenever you change a variable that needs to be persistent, use SetModLocalData. This *may* cause bloating though...the data will probably stick around even if the bashed patch is rebuilt without your patches. Then again, that may be desirable.
2) Store all your variables in Oblivion XP.esp. A stringmap would work nicely...whenever a patch script is run for the first time, check the array to see if there are any stored values. Whenever you set a variable, be sure to also update the stringmap. The data will stick around until Oblivion XP.esp itself is removed (which is probably ideal).
3) I think Pluggy has the ability to read/write text files, so you could store the data in there instead. Kinda overkill though.

Basically, just store all your persistent variables somewhere that won't get reset. You'd still have to wait on Bash to add the tag, but it is doable.


At one point I was looking at something like Pluggy to store stuff in text files, but I don't like to run Pluggy myself, so I wasn't too keen on that route. I'd like to avoid bloating and I don't need any of this stuff around if the patch is removed, so I don't think Get/SetModLocalData would be the best answer for this either. Interesting idea though - I'll have to remember those for future reference. My main concern with option 2 is that I have no idea of the scope of these other variables at this point. How big do I make the stringmap? I understand your idea and will keep it in mind if WB can't give me the new tags. I am curious about one thing you said though: you said that WB could do this but doesn't because variables would get reset. Your suggestion above gives a work-around for that. But this is all hypothetical anyway because WB can't merge these patches - correct? So I'm still left with waiting for the new tags, or I've missed something :)

PM thought the new tags were doable and I'm hoping they will be in the next release or two. I'm currently working on another project, so I don't need them right away, although I might start pestering PM to see if they do make it into the next release or two. :)
User avatar
Gracie Dugdale
 
Posts: 3397
Joined: Wed Jun 14, 2006 11:02 pm

Post » Wed Sep 01, 2010 3:15 pm

Yeah, Bash can't (or won't rather) merge your patches until the new tag(s) are in place, but this will be a problem even with the new tag(s). All the new tag(s) would do is force Bash to merge the records even if they're new. Bash can't automatically make it safe for you. Not easily at least....theoretically I suppose it could always assign the same formID even if the patch is rebuilt. In order for Bash to do that, it would have to know about every mod that wants new records to be mergeable, and they'd all need a unique formID. The formIDs would have to be essentially hard-coded in Bash, and each modder that wants new records merged into the bashed patch would have to request a range of formIDs that they can use. If two modders accidentally use the same formID in the bashed patch, Bad Things© would happen. If someone else wants to take a stab at that sort of implementation, they're free...but I think it'd be too messy, be extremely easy to break, and require too much maintenance.

As for the stringmap, you don't have to know its size ahead of time. Have one stringmap variable in Oblivion XP.esp that holds all the data for every patch mod.

Spoiler
scn VarStorageQSarray_var PatchToData


And have every patch mod be responsible for it's own data:
Spoiler
scn PatchQSlong bIsInitializedref rSomeReflong iSomeLong...Begin GameMode    If bIsInitialized == 0        If eval(ar_Size VarStorage.PatchToData) == -1 ;if PatchToData isn't initialized, create an empty stringmap.            let VarStorage.PatchToData := ar_Construct StringMap        EndIf        If eval(ar_HasKey VarStorage.PatchToData "PatchName") ;If the key exists, get the existing data            let rSomeRef := VarStorage.PatchToData["PatchName"]["rSomeRef"]            let iSomeLong := VarStorage.PatchToData["PatchName"]["iSomeLong"]            ...        Else ; Otherwise go ahead and make the necessary keys            let VarStorage.PatchToData["PatchName"] := ar_Construct StringMap            let VarStorage.PatchToData["PatchName"]["rSomeRef"] := rSomeRef            let VarStorage.PatchToData["PatchName"]["iSomeLong"] := iSomeLong            ...        EndIf        let bIsInitialized := 1    EndIf...; Whenever you set a local variable, also set the array variablelet iSomeLong := 1let VarStorage.PatchToData["PatchName"]["iSomeLong"] := iSomeLongEnd


If you don't want the patch mod to depend on whatever mod holds VarStorage.PatchToData, you can always use RunScriptLine or GetFormFromMod and GetArrayVariable. You know the drill.

This would be freely extensible...if you need more variables, just add them to the patch mod and the appropriate lines in the bIsInitialized section. Removing a variable is slightly trickier but not by much, just add a check in the bIsInitialized section to see if the key exists, and if it does, delete it. Otherwise it would stick around in the array unused until Oblivion XP.esp is removed.
User avatar
Aaron Clark
 
Posts: 3439
Joined: Fri Oct 26, 2007 2:23 pm

Post » Wed Sep 01, 2010 5:34 pm

Is there no way for Bash to reference a record other than by its form ID? I'm just throwing this out here, but what if Bash could reference a quest by ModName.QuestName instead? I guess I'm suggesting a mechanism to use base ID's instead. Then you wouldn't care what the form ID is and load order would no longer be an issue. I'm wondering if this could somehow be tied into the new tags. Maybe rather than forcing Bash to merge or import new records, these tags would allow Bash to reference records by a different mechanism, like ModName.QuestName. Is this feasible or am I completely off my rocker? :) Otherwise I think I follow your suggestion and will grab that and tuck it away.
User avatar
emma sweeney
 
Posts: 3396
Joined: Fri Sep 22, 2006 7:02 pm

Post » Wed Sep 01, 2010 11:47 am

I think your rocker imploded by thinking too much ;)

Oblivion refers to all* records by their formID. Regardless of how Bash refers to a record, it has to give it a formID when it writes the Bashed Patch.

If a formID within a mod changes to one that hasn't been in use, Oblivion thinks it's an entirely new record and that the old formID was deleted. Things disappear, things reappear that shouldn't, scripts / quests get restarted, etc. With careful design, quests and scripts can survive this (what we've been discussing).

A new concern is that if a formID changes to one that was previously used by a different record, Oblivion may blow up. Imagine that a player imports two scripts (Script1 and Script2) into their Bashed Patch and Script1 happens to get the formID 0xFE001234 and Script2 gets the formID of 0xFE001235. The player rebuilds their patch and the formIDs get switched...Script1 now has the formID of 0xFE001235 and Script2 gets the formID of 0xFE001234. This is bad.

Oblivion doesn't know that the scripts were replaced...it thinks the scripts were merely updated, so it doesn't reset the variables. Instead, it tries to fill in Script1's variables with the values previously belonging to Script2. Script2 gets a similar treatment. Confusion reigns, scripts fail, and the game could potentially crash. Luckily, this can still be worked around with careful script design...every time the game is restarted, you have to assume that every variable can't be trusted and needs to be filled in from the stringmap. Just replace the bIsInitialized check with GetGameRestarted.

Now imagine if the formIDs that got swapped belonged to two quests. The wrong quest could end up being stopped (or started). So an imported script cannot safely stop it's own quest. When the patch is rebuilt, it may result in a completely different quest being stopped.

If the formIDs that got swapped belonged to a script and a quest, I don't know what would happen. Presumably, Oblivion would notice that the formIDs refer to a completely different record type and treat them as new records. It could just as easily crash the game or cause oddities. This would have to be tested....if it does cause problems, it can still be worked around by breaking the available formIDs into ranges and restricting each record type to a specific range (0xFE000000 - 0xFE005000 are only assigned to quests, 0xFE005001 - 0xFE00A000 are only assigned to scripts, etc). That would ensure that a quest is only swapped with another quest if any swapping occurs. Complicates things quite a bit, but doable.

These are the sorts of reasons why this hasn't been allowed by Bash. Things get hairy fast.

*There are two (or three, depending on how you look at it) exceptions: Game Setting records are referenced by their editorID, Magic Effect records are referenced by their editorID (or mgefCode with OBME), and any record with a formID <= 0x0000800 is hard-coded in the engine.
User avatar
Yama Pi
 
Posts: 3384
Joined: Wed Apr 18, 2007 3:51 am

PreviousNext

Return to IV - Oblivion