DeadHerring

Allies
  • Content count

    12
  • Joined

  • Last visited

Community Reputation

0 Please Give Cookies

About DeadHerring

  • Rank
    Novice
  1. PROBLEM SOLVED. If a moderator could put [solved] at the start of the subject line, that'd be great! Thanks! [Edited] You were right, I was trying to call PositionCell on an activator object that was still trying to do something. It's rather obvious in hindsight. Even though the callback to the function script looks like it would be the last thing that's done in both branches of the logic, it isn't. Any use of "Call" stops execution at exactly that point and defers execution until the called function script exits. Which means that in both cases it was still inside the logic structure when PositionCell was called. I used to know a guy from Brooklyn who had a way of coming up with one-liners that really capture the feeling of the moment. For moments like these, I'd have to pick "I is a genius, yo!" Anyway, moving the call to PositionCell into a "cleanup" script that doesn't get called until the player exits the menu system stopped the CTD's cold. Hey, at least I finally figured it out. Cheers!
  2. Yeah, I've had that thought floating around the back of my head for awhile now, waiting for something I was doing with OBSE to break the game. Especially since I started working on this, which isn't that far from trying to use OB script like a programming language. At least it's a problem I can avoid. I'll keep experimenting with it, maybe I'll notice something. The fact that the behavior is so consistent, with one case always crashing the game but the other never having a problem, suggests a pattern. I wonder if having the text input handler obj's OnActivate block triggered might have something to do with it. The root menu launcher obj doesn't have one, just a flag variable that's set by an inventory token and evaluated in the GameMode block. Oh well, thanks for taking a look . And for indirectly getting my thinking on what I hope is the right track!
  3. No, the call is made from an unattached function script. The function script is called from the menu system's quest script, which fetches its ScriptID from the top of the page stack (an array). Not sure how that would affect anything, but that's the context. I'll double-check to make sure that the script isn't doing anything, but I'm pretty sure it's not. It shouldn't be by that point. ** I've double-checked the object script for the text input handler, and I'm not seeing anything obvious. It has a GameMode block with a conditional so technically I suppose it's always doing something (I'm pretty sure I know what you meant, though). Of course, the root launcher obj has one too. Other than that it only has MenuMode and OnActivate blocks. Here's the object script: Here's the function script: ScriptName OBGETextInputPageController ; ; Controls the behavior of the text input pages. ; ; Signature: (void) OBGETextInputPageController (Ref:StringMap) array_var argVector array_var pageData ref ProcessAndReturn Begin Function { argVector } ;=======Init====== If Eval (MenuSysCoreQ.ControllerMode == "Init") Let ProcessAndReturn := argVector->ProcessAndReturnAL ; Register self with call stack, cache page data and cleanup ; Call MenuSysAPISetSystemArg (ar_Map "ScriptID"::OBGETextInputPageController "CallBack"::OBGETextInputPageController) Call MenuSysAPIRegisterPage "%e" Call MenuSysAPICachePageData (ar_Map "ProcessAndReturnAL"::ProcessAndReturn "ArgVector"::argVector) ; Pass player input control to TextInputHandler and invoke TextInputHandler Let MenuSysCoreQ.ControllerMode := "Wait" Let MenuSysCoreQ.DeferInputProcessing := 1 TextInputHandler.MoveTo player TextInputHandler.Activate player 1 ;=======Restore====== ElseIf Eval (MenuSysCoreQ.ControllerMode == "Restore") ; Pass player input control to TextInputHandler and invoke TextInputHandler Let MenuSysCoreQ.ControllerMode := "Wait" Let MenuSysCoreQ.DeferInputProcessing := 1 ; TextInputHandler.MoveTo player TextInputHandler.Activate player 1 ;=======Wait====== ElseIf Eval (MenuSysCoreQ.ControllerMode == "Wait") ; Retrieve cached data Let pageData := Call MenuSysAPIRetrieveCachedData Let ProcessAndReturn := pageData->ProcessAndReturnAL Let argVector := pageData->ArgVector ; Move text input handler back to assets cell, reassert menu system input control and process return value ; TextInputHandler.PositionCell 2052, 2047, 8132, 0, OBGEAssetCell Let MenuSysCoreQ.DeferInputProcessing := 0 Call ProcessAndReturn argVector EndIf End
  4. Hey everyone. I've recently run into an aggravating and puzzling issue. I have an activator object that I'm using as a text input handler in the OBGEv3.1 Standalone Effects menus. This is originally located in a separate "assets" cell and moved to the player when needed. However, if I try to move it back to the assets cell with PositionCell (to get it out of the players "active" radius and save a few CPU cycles) the game CTD's every single time. What's puzzling is that I'm using the exact same technique for the root menu launcher without any problems. This isn't a deal-breaking problem. It doesn't matter that much if the text input handler object is active, the bulk of the code is nested in conditionals anyway. It's just annoying. And perplexing. I know that doing much of anything with persistent references has caveats, but why the consistently inconsistent behavior? If simply moving a persistent ref from one cell to another was going to break the game, we'd be in a lot of trouble. I'd almost have to guess there's a bug with PositionCell. I'm debating whether or not to stop using PositionCell on the root menu launcher object. It works on my game install and load order, etc., but is someone else going to have issues? Any advice would be appreciated. Thanks in advance!
  5. @ Arthmoor: Bookmarked. Great article! Good to know about the level engine bug too, that could've have made for some serious headaches. Thanks for the link, it answers a lot of questions I hadn't even thought to ask yet . I can also see how modifying persistent references can cause serious problems with save game files after the mod making changes is removed. Regardless of whether the mod breaks or the game CTDs because of the changes being made in the first place. Sounds like a good way to get your mod un-endorsed on tesnexus. Thanks, everyone, for taking the time to answer my questions . I think I know enough now to avoid these pitfalls at least. Hopefully there aren't too many more out there to find.
  6. Thanks for the reply . Sounds like persistent references are going to be a source of frustration and teeth-grinding no matter how long I work with the CS . But this at least gives me an idea of a few things watch out for. Curious that the NPC didn't go back to his old schedule when the records (esp) putting him there are gone. Hmm...AI state is stored in the save files, isn't it? All the state data would go in there. Otherwise the game couldn't resume on loading. Bear with me, fledgling programmer here, so I always try to figure everything out if it involves code somebody else's written, even Bethesda I've been told I tend to over-analyze too
  7. This is a bit of a hypothetical question, since I haven't tried to do it myself. Just trying to understand the logic so I don't make the mistakes in the first place. I ran across a post that I tried to help out with since it appeared to be a scripting logic problem on the surface of it. And hey, two mystified scripting newbies trying to figure things out is still better than one. We call it a learning experience where I come from. It came up in the course of the discussion that it may actually be a problem with modifying persistent references and scripts that were being added by the mod that this person was making a patch for. Nothing to do with script logic at all. Here's where I don't follow. I've been under the impression that modifying an asset from the vanilla game or another mod creates records in your esp that raise conflicts with the original content and win out, so your changes (being the latest) are integrated and supposedly made seamless with the original version if you've done things right. That's the whole point of a compatability patch, right? Meshing two mods together by merging records into a third esp to resolve clashes and manually tweaking things in the CS when there's no hard and fast rule for how conflicts should be handled? Unless I'm missing something, the unofficial patches use this mechanism to override buggy original content. The conflict resolution part of it anyway. Not the merging. So my question is this. Under what circumstances can you not modify existing assets? Does the story change when you start getting into persistent references with scripts attached, like activators? Or maybe a better question would be, what are the wrong ways to do it that should be avoided at all costs? And what about modifying assets that have already been modified from the vanilla version by another mod that you're patching? Assuming that the last esp loaded in always wins out, and the CS always generates complete record sets for anything that you've touched, RefID's intact and unchanged and all that, then how is this even an issue? I must be missing something... Hope I got the right forum for this question, seemed to be the best match. Thanks in advance, I appreciate any and all input!
  8. Thanks HeyYou, appreciate the feedback. I have another question. When I wrote the script, I was assuming that breaking the code up into small if/then blocks would let the script run more efficiently than having larger if/then/elseif blocks since it's an interpreted language and in a game like Oblivion memory consumption is a concern, so I'd want to keep the logic structures smaller. In contrast, if this was a compiled language, I would probably expect the compiler to optimize if/then/elseif blocks to be more efficient than isolated if/then blocks at the assembly level. Does breaking things up like I've done get me any efficiency boosts? Or does it not really matter that much in this case? In general, are there any ways to go about writing more efficient scripts? Hopefully I'm not over-thinking this. I'm coming from a programming language where even the little things can have consequences. I know this is scripting, not programming, but I still have to wonder what goes on under the hood. ** On the same note, how much benefit am I really gaining from tweaking fQuestDelayTime?
  9. I've begun writing a script that adds some OBGE screen effects to vanilla quests. I know OBSE topics aren't covered here, but that's not the focus of the advice I'm looking for anyway. I've put together a skeleton of the script to manage some special effects for the dream sequence portion of the Bravil "Through a Nightmare, Darkly" quest. No OBSE/OBGE specific code is included. This quest script just controls when the effects are turned on and off. Pretty basic. I wouldn't mind some input though, since I'm trying to come up with some conventions that will help me keep my script-writing clean and consistent, and hopefully avoid a few pitfalls as a bonus. I'd appreciate any comments on style, approach, or general script hygiene you care to share. ScriptName OBGEScreenEffectsMS05Script ; Convenience constants short FALSE = 0 short TRUE = 1 ; Processing control flags short bDelayTweaksOn = FALSE short bRelaxTweaks = FALSE short bKillEffectsProcessing = FALSE float fQuestDelayTime Begin GameMode ;=================================================================================== ; Script processing controllers - tweaks script execution delays for better frame sync when close to ; dream-state transitions. Tweaks are relaxed between transitions (when not close to final transition) to ; lighten CPU overhead. Processing is halted here after final transition. ;=================================================================================== If (GetStage MS05 > 10 && bDelayTweaksOn == FALSE) Set fQuestDelayTime to 1 Set bDelayTweaksOn to TRUE EndIf If (bRelaxTweaks == TRUE) Set fQuestDelayTime to 1 Set bRelaxTweaks to FALSE EndIf If (GetStage MS05 == 40 || GetStage MS05 == 75) Set fQuestDelayTime to 0.01 EndIf If (bKillEffectsProcessing == TRUE) StopQuest MS05ScreenEffects Return EndIf ;============================= ; Dream sequence effects controllers ;============================= ; Detect player entered in-dream quest stages and start effects If (GetStage MS05 == 50) ; Start dream sequence effects ; Relax script processing Set bRelaxTweaks to TRUE EndIf ; Detect player left in-dream quest stages and stop effects If (GetStage MS05 >= 80) ; Stop dream sequence effects Set bKillEffectsProcessing to TRUE EndIf End Things to note: Since I'm indirectly modifying a vanilla quest, I decided to make a separate quest and quest script to monitor progress through the target quest instead of modifying the original or adding activator objects to cells. From what I've read, quests aren't the most efficient way to run a script, but as far as I can see it's the closest thing to a global script that Oblivion has. And it should help avoid compatibility issues with other mods that might alter either Bravil interiors or quests. Blood & Mud comes to mind, but I haven't checked it. Thoughts? Counter-points? I've added convenience constants for clarity. I haven't tested to see if C-style declaration/initialization combos work in TES scripting yet. They compile, but the script engine may ignore everything after the variable declaration for all I know. A pointer there would be nice, but I'll find out sooner or later. If it does work, what do you think of the convention? My first script, so be nice Thanks in advance!
  10. I was hoping there was a less frustration-prone way to get a leg up on TES scripting, but fair enough. I would have had to do what you're talking about sooner or later anyway . Just to clarify, I'm not a programmer by trade...yet. Still need a couple of years before I can claim that. I've just been programming for a long time.
  11. First time on these forums, so here's a big "Hey Everybody!" to (you guessed it!) EVERYBODY. It's great to be joining the Oblivion modding scene! I've gone through some of the scripting classes, and so far so good. I'm picking up on a lot of caveats to using TES script though. Add to that the fact that I'm coming over from working with real programming languages. Compared to those (C++ and VB.NET) TES script appears to have some really odd conventions. Has anyone put together any refences or started any discussions that would help experienced coders transition over? Well, moderately experienced programmers anyway I know how to write code, and I can pick up a new syntax easily enough, but I have a feeling the "gotchas" are gonna be a nightmare! Thanks in advance, and happy coding!