Jordan Savant # Software Engineer

The Firmament Oblivion MOD - Part 2: Questing, Objects and Stages

The Firmament Image

This is Part 2 of this guide on modding Oblivion. In part 1 we stumbled through alot of the scripting and even mechanics of the engine to make functional mod, but I wanted it to be more in tune with the Oblivion experience. The pop ups worked, the powers worked, the note basically told you what to do, but if I wanted to embed this in the Lore of the game I felt that it needed a more guided experience that could enrapture the player character like other lore elements of the game.

Insert Questing into the mod!

Questing added the much needed polish to this experience and also shed a lot of light on the engine mechanics regarding questing and data. Some things I wanted the player to experience:

  • I wanted them to be guided into how to receive a blessing with questing steps and journal entries
  • I wanted to gate them from access until into the game at least a few levels in
  • I wanted the quest to be completable but always running to let them retain the perks

Quest Stages

So we had already added a script attached to an onrunning quest that used an internal state variable to check and progress the mechanics. But now we needed to begin to incorporate quest stages if we wanted the journal to reflect our needs.

Quest editor screen

I started perusing other quests and the main online guide on how to get started and roughed out the following:

  1. Under Character > Quests was the primary editor screen for all quests
  2. Each quest is divided up into stages under the Stages tab
  3. Quests could have linked conversation Topics and Dialogues for conversational elements of quests.
  4. A quest stage could have a Log Entry that populated our journal and also provided a popup notification of the even with the sound effect and icon
  5. A quest stage could run an immediate result script and also log entries were optional
  6. We could set and get quest stages for a quest with SetStage [QuestId] [Index] and GetStage [QuestId] respectively
  7. Quest stages could be changed from any script making interacting with objects like book cause changes in our quest script
  8. Each stage has an Index value and SetStage for any false index does not work, so we need to explicitely define all quest stages in the editor

Armed with this new information I set out to refactor the quest to include Quest Stages and wound up with this setup:

Firmament Quest Stages

These were the sages with their indexes I settled on and I will explain them in more detail below:

  • 0 is not listed and is the starting index for all quests
  • 1 runs after our note is added to our player inventory and notifies the player
  • 5 indicates we have read the note and do not have The Firmament book so we need to get a copy
  • 6 indicates we have read the note and already have a copy of The Firmament
  • 10 a followup of stage 5, we prompt the player to find a copy of The Firmament
  • 13 a followup of stage 6 or 10 we have a copy of The Firmament and prompt the player to read it
  • 15 the player has read The Firmament so we move to stage 20
  • 20 the player read The Firmament so we prompt them to wait until a clear night sky
  • 25 we notify the player that the conditions are ready to look at the stars
  • 26 the player was blessed looking at the stars
  • 30 we finish the quest and tell the player they can attain power continually now

Quest editor stages tab

Initialization and The Note

Stage 0 runs its own small state machine requiring the player to be at least level 5 before the quest can begin. Additionally we wait a day after they level up so we do not bombard them at one time on immediately reaching level 5. Once they do we drop the note into their inventory and move to Stage 1.

Note added screenshot

In Stage 1 the quest automatically notifies the player about the note and then stays in this state until the note is read. This is where we needed to add a script to the Note object in our game:

scriptname AAAFirmamentNoteScript

begin OnEquip

    ; after they have read the note lets see what state they should transition to
    ; if they do not have the firmament promopt to find one
    ; if they do state that they have it and move to environment detection

    if GetStage AAAConstellationQuest == 1
        if ( Player.GetItemCount Book3ValuableTheFirmament > 0 )
            SetStage AAAConstellationQuest 6 ; set to read complete w firm
        Else
            SetStage AAAConstellationQuest 5  ; set to read complete w/o firm
        EndIf
        ;Message "has read note"
    endif

end

Note read screenshot

This script runs whenever the book object is equipped by the player, which means when they read it from their inventory. When they do read it we check to see if they have a copy of The Firmament on them and then conditionally go to Stage 5 or 6.

When we look at Stage 5 and 6 we can see they are empty log entries and then in our main script they just transition to a following state. Why not just immediately jump to those stages when they read the book?

Well what I realized is that when we open the book it will immediately trigger the quest stage and show the quest popup which breaks the immersion, you don't have to read it. If I added the event to the unequip game mode then it would solve this but we would still have the quest popup occur while in the inventory menu. It felt more natural for the quest popups to be in the main game play mode and not in the menu modes so by creating intermediate transitions we can wait until they return to the game world to set the next stage, and thats what we do.

Note read screenshot

Reading The Firmament

If the note sent them to Stage 5 for not having a copy of The Firmament our script will then transition them to Stage 10 where we prompt the player to go fetch a copy. This is where we now must edit The Firmament object in-game with a new script:

scriptname AAAFirmamentBookScript

Begin OnAdd

    if ( GetStage AAAConstellationQuest == 10)
        SetStage AAAConstellationQuest 13 ; go to read
    EndIf

End

Begin OnEquip

    if ( GetStage AAAConstellationQuest == 13 )
        SetStage AAAConstellationQuest 15 ; go to having read it
    EndIf

End

Notice here that we listen for two modes: OnAdd and OnEquip. When the book is added to the players inventory we trigger Stage 13 which prompts the player to read the copy they just acquired. Additionally this is the same stage that we get sent to from the Note if they already had the book. From our original note it would send them to Stage 6 which then jumps to the same Stage 13 prompting them to read the copy they already had.

Note read screenshot

Our OnEquip event listener works similarly to our original Note in that once they read it we go to Stage 15 which is a gameplay transition stage. Once they have read and left the inventory menu we can trigger a change to Stage 20.

Note read screenshot

Detecting the Sky

In our previous version of the mod we needed the player to carry The Firmament and then be at night outside with a clear sky before they could look up and be blessed. But this was a little unguided. Also, now with our quest plotline having already incorporated The Firmament for the player it was unnecessary to force them to carry it around. They would likely sell it or something and lock off the quest powers for the remainder of the game and that would not be fun.

Note read screenshot

So at Stage 20 we prompt the player to wait until conditions described are met: that it is a clear night outside. Once we detect these environment changes we transition to Stage 25 where we notify the player their patience has been awarded and now they should look to the sky.

As an aside:

I was play testing this on my main character and this part of the quest triggered when I was fighting in the Arena of the Imperial City. The quest told me to look up and so I did and I was blessed with the powers of the Steed and was immediately boosted in combat for the fight. It was a good experience.

Note read screenshot

Technically Stage 25 and 30 are running the same block of our main script. It is detecting conditions are good and they look up and then proceed with the monthly blessing. But Stage 25 has a few additional conditions:

  • We cannot trigger The Serpent in this stage so our player is not cursed for their first experience with this quest
  • Once we detect they are blessed we transition from Stage 25 to 26

Stage 26 existed because if we triggered our quest complete when they were blessed we would receive a double pop up, one from our MessageBox for the blessing and one for the final quest stage log entry. So 26 let us complete the MessageBox blessing before moving on.

Once we finally transition to Stage 30 we provide our final Quest Complete log entry. This does not actually stop our quest script as we are supposed to do that with code. But for us, we do not want to stop the quest, we want it to run in the background providing our continual blessings.

Note read screenshot

Thankfully the engine allows this, the player gets the satisfaction of a newly completed quest while our script can continue to run in perpetuity to bless them.

Note read screenshot

Nexus Page

At this point I felt the mod was complete. I would play test a bit more but then add it to Nexus for others to enjoy.

Feel free to download the Mod on Nexus.