Thanks. I changed the info in my previous post.
Repeatable Bounty Quests, Game: TES IV: Oblivion This one is going to discuss how to make a revolving, never-ending, set of bounty quests, similar to what Skyrim has, when we get bandit raids from innkeepers. My version is different from Skyrim's though, in several ways. Bottom line: If you're the type of gamer who wants to be sent off to do random kill-type missions, which are also repeatable, this is what is going to be taught in this post.
Here is what I decided to create in my game. Count Marius Caro begins to sponsor endeavors to clear out certain lairs of whatever scummy enemies they hold. My character (Lady Saga) will be able to go into Leyawiin's castle, speak to a certain NPC agent, and then select a location to plunder. Once she finds the location and eradicates a specific boss, the game informs the player that the boss has been taken care of. And now a reward can be collected back in Leyawiin's castle.
Though this sounds like just another kill quest, again, the main difference is this one can respawn itself. And multiple locations can be added.
1a). Fire up the Oblivion Construction Set.
1b). First thing to do is start a new quest. Give it an ID. Quest Name is not important (as will be seen, the name of these quests will never appear in-game), but you can name it just for reference, here in the Construction Set. For this lesson, I am giving an ID called aaaBountyQuest, which can be changed to whatever you'd like.
1c). In the quest's Data tab, start a script which looks like this...
-------------------------
scriptname aaaBountyQuestScript
short DoOnce------------------------------
"aaaBountyQuestScript" can be made more specific, especially if you want to make this script more regional. In my game for instance, I've got aaaLeyawiinBountyQuestScript.
1d). Change the Script Type scroll bar from Object to Quest.
Save that script (using the save icon) and close it. Click OK, closing the quest window. Reopen it, find the script you just started, select it, and click OK (closing the quest window again).
Next, we're going to edit a letter, a town-based NPC, and an enemy NPC. All of this happens in the steps below.
2a). OBJECT window > Items > BooksEdit a handbill, or a letter, or a note, etc. Give whatever parchment you decide to edit a new ID. It makes sense to associate this ID name with whatever lair it's going to direct the player to. My first note will send the player to Undertow Cavern for instance, so I'm calling the note's ID aaaUndertowQuestNote, and then changing its Name to Undertow Cavern Order.
2b). Change the note's Book Text too, of course. Write some material describing that (1) there is a problem at a nearby lair (whether it's Undertow or somewhere else), and (2) a reward can be had after this lair is dealt with. Write something like...
Hear ye, hear ye!
By order of the County of Leyawiin, this parchment shall direct its bearer towards the subterranean dwelling known as Undertow Cavern. Once riddance and eradication of Undertow's scum has been accomplished, We of the County of Leyawiin shall have knowledge of its leader being taken down, through the glass of our specialized crystal ball. Thence, the bearer of this note shalt return toward our magnificent domain, and payment of 200 gold shall be dispensed.
~ Count Marius Caro~ 2c). Ahem. It's a good idea to make this note a Quest Item. Here is why: This method of quest-making does not use stages at all. So the note is the only reminder a player will have, explaining where to go.
And don't worry. This quest item/note won't get stuck in inventory forever; it's going to get removed later on, or its quest-status is going to get removed.
3a). OBJECT window > Actors > NPCEdit a named (not generic) Bethesda NPC who is not associated with Shivering Isles. This is going to be the guy or lady who will dispense quest locations.
If you have already made an agent and wish to reuse him or her, you can just skip to step 4a, whcih teaches how to make the enemy. 3b). Remove the NPC's script (if there is one), and also get rid of any AI. Change the NPC's Class to Agent. Edit the NPC in any manner you'd like.
I edited Agamir, removed his script, changed his Class from Thief to Agent, amd removed all his AI and Factions. Changed his ID and Name, bla bla bla. I transformed Agarmir into the "Leyawiin Quest Agent". Since this agent lives in Leyawiin Castle, I made sure to add him into the LeyawiinFaction (so he'll occasionally gossip about local topics), and also LeyawiinCastleFaction.
An optional step is to give the agent some AI (skip to step 4 if you just want to move on to the quest-making part). I gave him AI which causes him to Travel from the castle's court area into its Servants' Quarters. Most important though, I made a 'Use Item At' package called aaaLeyawiinAgentOnDuty. I then toggled Must Complete on. And changed the Time scroll-bar to 9, with a Duration of 8, meaning that he'll be "on duty" from 9 to 5. I gave him a desk to sit at (WorldObjects > Static > LowerClassTable01), and a chair to sit upon (World Objects > Furniture > UCChair05L). Gave the chair a Reference ID so the agent would sit down while "on duty". All of these furniture pieces were put off to the side of Leyawiin Castle's Great Hall.
.....If you want to do something simliar, just make two Travel packages: one which causes the NPC agent to travel to some other location, and another which causes him/her to return to work. The third AI package (Use Item At) makes the agent sit down from 9 to 5. I went into the agent's Use Item At again, and clicked on the Location tab. Toggled 'Near Reference' on, and then pushed the Select Reference in Render Window button. Double-clicked on the chair added earlier. Clicked OK.
Overall, he will travel to Leyawiin's court area at 7 am, sit down at 9, and stay there until 5. After 5, he walks to the Servants' Quarters, where he basically stands around doing nothing. Lol. You don't have to do all this. I like dynamic NPCs though.
4a). OBJECT window > NPCFind a generic enemy who will be appropriate for whichever cell you'd like to plunder. Since I chose Undertow Cavern (which hosts Black Bow Bandits) I went into the Redguard section, and then edited BanditBlackBowBoss4Male1.
4b). Change ID, and change Name if you'd like. Toggle Respawn on, and toggle No Low Level Processing off.
Since the NPC I edited is already a Black Bow Bandit, he already has the correct factions and AI. It's always good to double-check these features, though.
4c). Stats tabNow's the time to make the enemy boss into whatever he or she is supposed to be. Whether he's a wimp, or an über.
Take the time to set the enemy up for combat.
Tip: There are two basic ways to set up the enemy's Health, Magicka, and Fatigue: these stats can either be fixed, or Leveled. PC Level Mult will make an enemy who levels with the player/character, or below / above the PC. This is my favorite way to set up enemies. Problem is, I have found that sometimes the game's engine screws up when respawning the enemy, leaving him or her with zero Health, and (sometimes) a huge negative number for Fatigue.
The only way I've found to fix this is to click PC Level Mult off. This will cause the CS to automatically choose Auto Calc Stats instead. Click Auto Calc Stats off too. Now it is possible to choose any numbers, not just for Health, Magicka, and Fatigue, but also for all the Attributes, and wherever else there is a slot which can be modified.
It is also possible to use scripts, so that these numbers get generated in real-time back in-game. But this too me seems overly complicated, like it could also welcome new problems in the future. I like keeping things simple.
4d). Inventory tabAll generic Bethesda enemies use Leveled Lists to determine what gets added into their inventories, so I personally don't mess with this tab. Leveled lists give random things to NPCs, to wear and use. Because of this, the enemy boss will be a little bit different every time he gets encountered, since he'll be wearing different armor / carrying different weapons, every time he respawns.
Go ahead and add or subtract whatever you'd like, though.
5a). CELL + RENDER windowsPlace the NPC enemy into whichever cell he /she belongs in. It's a good idea to put him/her into a final room, so that the PC will be forced to defeat most of the lair before the boss is found. Once the enemy is in place, he or she might be in underclothes.
This is okay. Those leveled lists will handle this dilemma; giving the NPC something to wear, and carry, once we're back in the game.
5b). Give the enemy a Reference ID. For this tutorial, I am calling it aaaEnemyBossRef, but for my actual game I chose aaaUndertowBossRef. It's a good idea to copy whatever ID is chosen, so it can be pasted into scripts later on.
5c). Toggle Persistent Reference on, if it's not already on.
5d). Also, start a script for the enemy that looks like this....
---------------------------------
scriptname aaaEnemyBossScript
short Dead-------------------------------
Substitute "EnemlyBossScript" with whatever name is more specific. In my game, I've got aaaUndertowBossScript.
5e). Save that script (using the save icon), and close it. Click OK, closing the NPC's panel, and click OK again, closing his or her Reference panel. If you're editing the NPC from the Object window (instead of its Reference window) you won't need to close a Reference panel.
5f). Reopen the NPC's panel(s), and find the script you started earlier. Click OK again (closing the NPC and Reference panels if both were opened) SAVE all progress using the main toolbar, and reopen the NPC's panel(s) again.
Though all of that opening & closing seems redundant, it's actually necessary to follow those steps, in that order. If you don't, sometimes problems can happen. The script might give annoying error messages later on when we're trying to save it, for instance.
5g). Now, to add more to the script.
------------------------------------
scriptname aaaEnemlyBossScript
short Dead
Begin OnDeath
If (aaaEnemyBossRef.Dead == 1)
Set aaaEnemyBossRef.Dead to 2
Set aaaBountyQuest.DoOnce to 2
Message "The leader of X has been killed", 36
EndIf
End---------------------------------------------------
Substitute "aaaEnemyBossRef" with the Reference ID of your enemy, if you gave him/her some different Reference ID name.
Substitute X with whatever location name was chosen.
Note the message, too. Since this method of quest-making does not use stages, it's important to be informed of the boss's death in real-time, just so you know the quest is working. This message will not show up as a quest update (it will not pause the game). If you still find this to be immersion-breaking, just delete that whole line of text.
5h). Use the Save icon to save the script before it's closed. Click OK on the enemy's information panel(s).
5i).. RENDER window: Get back into the cell where the enemy is. Now go into the OBJECT window > WorldObjects > Static, and pull an XMarkerHeading from the Object window into the Render window. Give this XMarkerHeading a Reference ID. I am calling it aaaXMarkerHeading for this lesson, but this can be changed to something more specific, as per the enemy's name, for instance. The XMarkerHeading be discussed later in this post.
6a). QUEST window > Quest Data tabReopen the quest which got started earlier in this tutorial.
6b). Priority can be anywhere from 10 to 70, depending if the quest is going to 'compete' with others out there. For instance, if you only use the one NPC agent added during 3a, Priority can be set low. If you're going to include other NPCs (let's say Count Marius Caro or some other NPC gets spoken to, to introduce the character to this new concept of bounty hunting) Priority should be set higher, since other quests associated with the extra NPCs might prevent the bounty quest dialog from showing up.
6c). Make sure Start Game Enabled is toggled on (it should be, by default) and add
GetIsPlayableRace == 1.00 goes into the Quest Conditions window.
6d). Return to the script. Time to add a few more lines of text, so that it'll now look like this...
--------------------------------------
scriptname aaaBountyQuestScript
short DoOnce
short Timer
short StartDay----------------------------------
Close and save, bla bla bla...
7a). Topics tabAs usual, start with a GREETING. "How fares thee? ... Have you come to take down one of our nearby locations?" is an example of what the NPC Agent could first say. Here are the Conditions.
GetIsID 'aaaQuestAgent' == 1.00 AND
GetQuestVariable 'aaaBountyQuest', DoOnce == 0.00Substitute "aaaQuestAgent" with whatever ID you actually chose.
7b). Use the Add Topics box to to add a custom topic, and (as usual) add this topic into the Editor ID window as well. I am calling this topic "aaaBountyQuest01"
7c). During aaaBountyQuest01 (or whatever you named your topic), the Agent explains what's going on locally, with forts and caves and ruins all harboring lots of baddies. The agent then asks if we'd like to see a list of possible places to plunder.
The cool thing about this type of quest (once it is all set up) is we can add several locations to go to, later on. And all of these locations get chosen through dialog. Conditions from the GREETING can be copy / pasted. Again, they go like this...
GetIsID 'aaaQuestAgent' == 1.00 AND
GetQuestVariable 'aaaBountyQuest', DoOnce == 0.007d). In the Result Script box, type this:
Set aaaBountyQuest.DoOnce to 17e). In the Choices window, right-click > New and make a second custom topic, dealing with whichever lair is being featured. So in my game, I've got aaaUndertow as a topic ID.
Add that topic into the Editor ID window, too. This topic is going to be the first locational topic. As I said, more locations (and topics for each location) can be added later, each one getting its own dialog.
7e). For this first locational topic, do all the usual steps: change Topic Text to something in plain English (if needed). Make some dialog which furthers the conversation "Ah, so you'd like to head to Undertow Cavern...." The agent explains whatever local problems the town has been having with Undertow, then. "Located off the west gate, right above the town. Such a menace to the stable and travellers below..."
Conditions go like this....
GetIsID 'aaaQuestAgent' == 1.00 AND
GetScriptVariable 'aaaaEnemyBossRef', Dead == 0.00That script variable function is an awesome tool, by the way. Variables are what often cause the game to allow, or not allow, all sorts of things. Same goes for the quest variable used in the first Greeting. Script and quest variables shall get used a lot during this entire process.
7f). If you want to make this moment into a Yes or No choice, use the Choices window to add Yes and No topics. If not, skip to step 8.
.... The "Yes" choice is going to be specific to Undertow Cavern (ID name is aaaYesUndertow, for instance). The "No" choice is going to be much more generic (aaaNo), and will pertain to any moment the player clicks on "No" during conversation. In fact, if you already have a "No" topic from previous quests, you can just reuse this.
7g). Add both Choices (aaaYesLocation and aaaNo) into the Editor ID as well, and add dialog for each one. If you want some dialog which explains where the lair is, you can type this in too. "Let me put that location on your map."
Conditions for the "yes" topic are the usual GetIsID and script variable...
GetIsID 'aaaQuestAgent' == 1.00 AND
GetScriptVariable 'aaaaEnemyBossRef', Dead == 0.00 In the Result Script box, type these in....
Set aaaEnemyBossRef.Dead to 1
Player.AddItem aaaQuestNote 1
ShowMap UndertowCavernMapMarkerSubstitute "aaaEnemyBossRef" with the Reference ID of your enemy.
Substitute "aaaQuestNote" with the ID of the note made during step 2..
Substitute "UndertowCavernMapMarker" with the name of the location, unless you also are using Undertow, of course. 8a). Assuming you don't already have a "No" topic, make some dialog like "STOP WASTING MY TIME!" in response to our character opting out. Only one Condition is needed, which is the same GetIsID from previous steps.
8b). Result Script should be
Set aaaBountyQuest.DoOnce to 0 8c). Toggle Goodbye on, to simulate the Quest Agent losing temper, if you'd like!
Note: notice the QuestVariable up above in step 8b. It started out as 0, changed to 1, and now it's 0 again. What's that all about? Well, the way this bounty quest works is: we can only choose one quest location at a time. This is important. If we accept a quest (Undertow Cavern, for instance) and then immediately accept another one (assuming you write in more than one location), this will confuse the game's dialog, and screw it all up. It is possible to make more than one location at a time viable, but the amount of work it'd take is just not worth it. Much better to keep things simple!
So it's important to have a way to make sure only one quest location at a time gets focused on. But it's ALSO important that dialog is able to reset itself to the very beginning ("How fares thee?") so that the entire process can be started over.
>> This entire bounty quest idea works on timer scripts, which will get written up in a few moments. After a location gets accepted, its leader get killed, it is these timers which cause the quest to reset. 9a). Go back into the first locational topic (the one which describes where to go, and why to go there). Right-click > New into the Info window. Write some dialog which explains that a certain location has already been plundered.
For instance, let's say Undertow Cavern has already been eradicated, its timer has not reset, and its enemy has not respawned. The player forgets this though, and clicks on Undertow Cavern. Dialog in this situation can go like "Hmm. Seems you have already cleared that location. No need to go there again; Undertow's enemies have not returned. Would you like to choose another location?"
9b). Conditions ....
GetIsID 'aaaQuestAgent' == 1.00 AND
GetScriptVariable 'aaaEnemyBossRef', Dead >= 2.009c). In the Choices window, add any other locations which have been set up so far. In my game for instance, I've got aaaFortDoublecross and aaaFortTeleman in this window. Of course, if this is the first time setting all of this up, there won't be any other locations, yet.
Also, add in that "no" topic again, so the player has a choice to opt out entirely.
10a).
Quest Data tabTime to finish up the main script. Here is what it'll look like. Again, this will be a timer script.
------------------------------------
scriptname aaaBountyQuestScript
short DoOnce
short Timer
short StartDay
Begin GameMode
If (Timer == 0)
If (aaaEnemyBossRef.Dead == 3)
Set StartDay to GameDaysPassed
Set Timer to 1
EndIf
EndIf
If (Timer == 1)
If ((GameDaysPassed - StartDay) >= 3)
Set Timer to 0
Set aaaEnemyBossRef.Dead to 0
EndIf
EndIf
End---------------------------------------------------
* To summarize, the script above will start its timer after we speak to the NPC agent, and are rewarded. The dialog for this reward has not been written yet, but we'll get to that later. After the timer starts, it will reset the quest once 3 days have passed. After those 3 days have passed, voila, the agent's dialog updates, which can potentially send us off to that same lair again. In that lair, the NPC enemy respawns, along with the cell he or she is in.
** It is possible to change the timer to your liking. If 3 days seems too soon, just change the "3" in If ((GameDaysPassed - StartDay) >= 3) to some other number. Changing this to 10 will make sure dialog doesn't reset until 10 days have passed, for instance.
*** 3 days happens to be the realistic minimum here, though. Since Bethesda cells don't reset until 3 days have passed, it's pointless to make dialog which resets before then (sending us off to that same lair), if the cell itself hasn't reset yet. Only for testing purposes should you try less than 3 days. Making the script reset after one day, for instance, is an experiment you can try just to see if the original dialog resets.
10b). Save the script and close it, close the Quest window, save, bla bla bla....
These next steps are optional, and deal with adding map markers and quest targets. If you don't want to add these, skip to step 12.
11a). CELL + RENDER windowsGo into the cell where the enemy got added, and find the way out of this cell, by clicking on the lair's Door Markers. Since I chose Undertow Cavern, this isn't such a task for me.
I only have one cell to exit from.
11b). Once you are outside this cell, try to find its Map Marker. Hopefully there is one! If not, you'll need to make one. Anyway, leave this marker on-screen.
11c). QUEST window > Quest Targets tabRight-click into the large Target Ref window and select New.
11d). Click on the Select Reference in Render Window button, and double-click on the Map Marker.
11e). Right-click > New into the Conditions box, and add GetScriptVariable 'aaaEnemyBossRef', Dead == 1.00
11f). Go back into the Topics tab and find the "Yes" response (if you added this). Add some more dialog that goes "I will mark the location on your map."
11g). In the Yes topic's Result Script box, type ShowMap XMapMarker, with "X" being whichever lair the quest pertains to. So an example is
ShowMap UndertowCavernMapMarker To summarize, by now there should be five topics in this quest: the initial GREETING, the initial topic which follows the GREETING (in which the agent explains where some trouble areas are in Cyrodiil), a topic which discusses a specific lair (Undertow Cavern, in my case). Then there should be Yes and No topics, with the "Yes" being a specific topic sending the player to a specific lair, and the "No" topic being more generic.
12). Save, goshdarnit!
13a). Time to make a second GREETING, which shows up if the PC has started a quest, but has not completed it yet. "Ah, you are back. How's your latest expedition coming along?"
Conditions ....
GetIsID 'aaaQuestAgent' == 1.00 AND
GetQuestVariable 'aaaBountyQuest', DoOnce == 1.0013b). Use the Add Topics box to move the conversation toward the same custom topic created in step 7b. This time though, write some dialog which says "Seems you've already got a quest to follow. Finish that one up, then come see me."
13c). Copy all the conditions from the GREETING just above, and paste them into this "Seems you have already...." topic. Toggle Goodbye on, if you'd like.
14a). Time to write the reward stuff. Start a final GREETING in which the agent is glad to see us return. "You've made it back!" Give the agent a surprised look, perhaps. The agent is amazed how good our toon is.
GetIsID 'aaaQuestAgent' == 1.00 AND
GetQuestVariable 'aaaBountyQuest', DoOnce == 2.0014b). Use the Add Topics box to link to a "reward" topic. If youv'e already got one of these made from previous quests, you can just use this again.
14c). "Here is your reward.... bla bla bla" says the agent.
GetIsId 'aaaQuestAgent' == 1.00 AND
GetScriptVariable 'aaaEnemyBossRef', Dead == 2.0014d). In the Result Script box, type ...
Set aaaBountyQuest.DoOnce to 0
Set aaaEnemyBossRef.Dead to 3
Player.AddItem Gold001 X
Player.RemoveItem aaaQuestNote 1Substitute .... well, you know what to do by now, right?
The "X" can be whatever number you'd like. 200 gold, 2000 gold, whatever.
Note the RemoveItem part, which removes the note which initially sends the player off to Undertow, or wherever. If you made this note a Quest Item, now you don't have to worry about getting it out of inventory. Another option: if you want to keep this note in some desk (perhaps your character is some sort of pack rat) yet the note is a Quest Item, just type
SetQuestObject aaaQuestNote -1 Now for the final touch. Since the enemy boss is not generic, he or she tends to stay wherever he/she winds up. In other words, if the boss fight causes the player-character to flee to another location (even outside the lair) and the boss gets killed in that other location, THIS is where the boss will respawn. So here's how to put the boss back into that initial room. In fact, the boss will respawn exactly where the XMarkerHeading from step 5i was placed.
15a).
OBJECT window > World Objects > StaticClick on anything in the right side of the Object window, and press X.
15b). Go into the lair where the enemy boss is located (unless the Render window is still showing this boss).
Now, if the enemy is in a multi-celled lair (for instance, if the enemy is in UndertowCavern02 instead of UndertowCavern01) you'll want to get into that initial cell, in this case, UndertowCavern01. If the enemy is in a lair which only has one cell, that'll be less work.
15c). Get to the initial cell's entry door. Typically, this is going to be the very FIRST door the PC walks through, to get into that initial cell.
15d). Go back to the Object window, and drag an XMarker from this window into the initial cell. Try to place this XMarker somewhere right behind the initial door, right on its floor. Give this XMarker a Reference ID. I am calling it aaaXMarker for this lesson.
15e). Save.
16a)
QUEST window > Quest Data tabOpen up the main script. And add this script anywhere onto this page between its Begin / End block...
If (aaaNPCBossRef.Dead == 1)
If (Player.GetDistance aaaXMarker <= 500)
aaaNPCBossRef.MoveTo aaaMarkerHeadingRef
Message "I have entered the lair called X. The evil, it simmers from within...", 30
EndIf
EndIfThis script will ensure that the enemy boss gets moved back where it should be, in real-time, and its message lets the player know the script has worked. The only possible remaining issue is if that enemy somehow got located outside of his/her lair. If so, another idea is to attach aaaNPCBossRef.MoveTo aaaMarkerHeadingRef into the Result Script box when the reward is given.
Using the XMarker script works most reliably though, since it's very rare the boss will get outside that lair and into the open world. This script can go anywhere within the Begin GameMode / End block. To keep things nifty, I like to put it outside of any other If/EndIf blocks. Example of the final main script is below.
scriptname aaaBountyQuestScript
short DoOnce
short Timer
short StartDay
Begin GameMode
If (Timer == 0)
If (aaaEnemyBossRef.Dead == 3)
Set StartDay to GameDaysPassed
Set Timer to 1
EndIf
EndIf
If (Timer == 1)
If ((GameDaysPassed - StartDay) >= 3)
Set Timer to 0
Set aaaEnemyBossRef.Dead to 0
EndIf
EndIf
If (aaaNPCBossRef.Dead == 1)
If (Player.GetDistance aaaXMarker <= 500)
[indent]aaaNPCBossRef.MoveTo aaaMarkerHeadingRef
Message "I have entered the lair called X. The evil, it simmers from within...", 30
EndIf
EndIf
EndAnd that is all. All sorts of dialog can be written to enhance this type of quest. Greetings and topics can be made for townspeople for instance, making them praise and glorify our character through random dialog (or curse him or her, if they happen to feel compassion toward baddies). But for the basic revolving quest itself, everything above shall send the player off to one initial lair, which can be repeated later on (days, months, years later). Replayability, that's what it's all about.
In the next post, I'm going to discuss how to add extra locations to this same quest.
This post has been edited by Renee: Nov 17 2019, 02:11 AM