Author Topic: Romance Authoring Tutorial  (Read 17720 times)

Offline Rastor

  • Planewalker
  • *****
  • Posts: 271
  • Author of the book, "Being a Jerk for Dummies"
    • RPG Dungeon
Romance Authoring Tutorial
« on: June 27, 2004, 06:28:05 PM »
I thought some people might like to read this:

http://www.rpgdungeon.net/tutorials/romance_tutorial.html

Offline Kyrien

  • Planewalker
  • *****
  • Posts: 5
Re: Romance Authoring Tutorial
« Reply #1 on: May 30, 2006, 01:39:59 PM »
Could someone repost that tutorial in this thread? It seems that site is somewhat slow these days about new registrants.

Offline icelus

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 3173
  • Gender: Male
Re: Romance Authoring Tutorial
« Reply #2 on: May 30, 2006, 01:43:11 PM »
Forced registration to view a tutorial.  Such administrative efficiency!

Sorry, I can't access it, either.
<Moongaze> Luckily BWL has a very understanding and friendly admin.

Offline Kyrien

  • Planewalker
  • *****
  • Posts: 5
Re: Romance Authoring Tutorial
« Reply #3 on: May 30, 2006, 01:52:09 PM »
What a quick response for such an old-standing forum. Thanks, anyway.  :)

Does anyone else have a long-standing valid account for that forum?

Offline icelus

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 3173
  • Gender: Male
Re: Romance Authoring Tutorial
« Reply #4 on: May 30, 2006, 01:57:32 PM »
Maybe we should register some with www.bugmenot.com

In the meantime, maybe see if you can access it via the Wayback Machine: http://www.archive.org

<Moongaze> Luckily BWL has a very understanding and friendly admin.

Offline Kyrien

  • Planewalker
  • *****
  • Posts: 5
Re: Romance Authoring Tutorial
« Reply #5 on: May 30, 2006, 02:54:28 PM »
The former seems like a great tool for net goers, but the latter won't load for me.

Oh well. :) I'll put more effort into getting this tutorial when it comes time.

Offline icelus

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 3173
  • Gender: Male
<Moongaze> Luckily BWL has a very understanding and friendly admin.

Offline Kyrien

  • Planewalker
  • *****
  • Posts: 5
Re: Romance Authoring Tutorial
« Reply #7 on: June 09, 2006, 03:58:43 AM »
Awesome! Thanks!

Offline Mobius572

  • Planewalker
  • *****
  • Posts: 11
  • Gender: Male
  • A God among Men
Re: Romance Authoring Tutorial
« Reply #8 on: January 30, 2010, 09:21:29 AM »
For those of yoou too shamelessly lazy to read the webpage, here is what it says:

It has been brought to my attention recently that many people with great ideas for romanceable NPC mods don't know where to begin.  They try looking at already existing romanceable mods and are immediately innundated with a variety of variables and numerous dialogue files and don't know how to make any sense of it.  The seeming necessity to make flirtpacks in today's mods makes this all the more challenging and baffling.  If this sounds like you, read on!

 

Globals
Bioware's default romances are driven by a number of globals.  Essentially, these are the basic ones:

 

"XXXXXMatch","GLOBAL":  This global is set to 1 if the NPC will romance the player and set to 0 if the NPC and the player won't romance.
"XXXXXRomanceActive","GLOBAL":  This global is set to 0 if the romance hasn't started, 1 if the NPC is talking with the player but isn't in love with him/her yet, 2 if the NPC and the player are involved in an exclusive romance, and 3 if the romance has been killed for whatever reason.
"XXXXXRomance","GLOBAL":  This is a timer that controls when the NPC will next talk to the player.  Whenever it hits 0, the game checks for the necessary prerequisites for a talk and has the NPC talk to the player if appropriate.
"Lovetalk","LOCALS":  This simply controls which dialogue the NPC will say to the player whenever it is time to speak again.

 

There are a number of NPC specific variables present in each romance as well, but those control things like quest progression, whether the NPC and player have had sex or not, etc.  Those are not explicitly covered in this tutorial.  If you write your own scripts for your NPC, you can implement these things as necessary.

Flirt packs generally use similar but differently named variables to the ones described above.  They do not have to, however.

 

Writing Talks
WeiDU is by far the best tool to use for writing dialogues.  The reason for this is ensuring compatibility with other mods.  Now, you may be wondering how you go about coding your lovetalk.  Well, first I would strongly recommend having your entire dialogue tree (NPC statements and corresponding replies) sketched out on paper first.  This will make things much easier on you.

Having your NPC start a dialogue is very similar to any other dialogue initiated by an NPC.  What you'll need to do is to include a block in your NPC's override script that says something like:

 

IF
 Global("MynpcMatch","GLOBAL",1)
 Global("MynpcRomanceActive","GLOBAL",1)
 Global("Lovetalk","LOCALS",1)
 GlobalTimerExpired("MyRomance","GLOBAL")
 !AreaType(DUNGEON)  // None of the Bioware NPCs will banter in dungeons, and I suggest that modders keep this tradition.
 !StateCheck(Player1,STATE_SLEEPING)  // How's the PC going to talk if he can't do anything?
 InParty(Myself)  // Jaheira will actually fire lovetalks if she's not in the party.  You don't want your NPC to do that, do you?
 See(Player1)
THEN
 RESPONSE #100
  IncrementGlobal("Lovetalk","LOCALS",1)
  Interact(Player1)
END

 

Then in your NPC's B dialogue file (you can also use J, but that's quite unconventinal), you'll need to include the NPC's dialogue:

 

IF ~Global("MynpcRomanceActive","GLOBAL",1) Global("Lovetalk","LOCALS",2) Global("MynpcMatch","GLOBAL",1) GlobalTimerExpired("MyRomance","GLOBAL")~ THEN BEGIN RomanceTalk1
  SAY ~blah blah blah~ // You'll type whatever your NPC says into the dialogue
  IF ~~ THEN REPLY ~blah~ DO ~RealSetGlobalTimer("MyRomance","GLOBAL",30)~ /* You can actually set the timer to whatever you want. */ THEN GOTO NextLine
  IF ~~ THEN REPLY ~blah2~ DO ~RealSetGlobalTimer("MyRomance","GLOBAL",30)~ THEN GOTO NextLine2
END

 

That's the basic pattern to do lovetalks.  Anything that's not a top-level text (starts the conversation) is done using basic WeiDU techniques.  Simply change the variable names for conditionals as needed to get your romance coded.

 

Flirtpacks
While flirtpacks are by no means necessary for a romanceable NPC, many modders choose to include them most likely because every other NPC mod out there with a romance includes them.  So, how do you code them?  It is actually not much different than romances.

In the NPC's override script:

IF
 Global("MynpcRomanceActive","GLOBAL",1)
 GlobalTimerExpired("Flirt","LOCALS") // This can be a local or global variable.  It doesn't really matter.
 See(Player1)
 InParty(Myself)
 !StateCheck(Player1,STATE_SLEEPING)
THEN
 RESPONSE #100
  StartDialogue(Player1)
END

 

Many modders like to use a counter to measure the number of times that the player flirts with the NPC.  While you are certainly able to do this, it is not really necessary. The reason that this is done is if you want to keep track of how affectionate the player is to the NPC. This could be useful if you are trying to do something such as including special dialogues for more affectionate players.

Use the same techinique as you used to code the NPC's lines for the romance dialogue, only this time put the lines into the NPC's J file.  The flirtpacks and romance dialogues should go in different dialogue files.

For player initated flirts, all you need is a dialogue state in the NPC's J file (must be J file) that says IF ~IsGabber(Player1)~ THEN BEGIN FlirtSelection.

 

Weighting
To force the romance dialogues to fire exactly when you want them to, the romances should be weighted sequencally so that the first lovetalk gets the lowest weight, second one gets second lowest, etc.  The same applies to flirts.

Often, you'll want these to be the lowest weights in the dialogue file.  This will ensure that the game will check the romance talks first to attempt to find a banter to fire.  If you don't do this then your NPC might skip over lovetalks occasionally or whatnot.

Now you have all the basics needed to code a simple NPC romance.

 

Advanced Possibilities
By now you've realized that what's been covered so far is barely anything that can (and almost always) is done with NPC romances.  Flirts have random options, certain lovetalks only go off when the player rests and after the player wakes up, NPCs may have fights that spawn in at a certain stage of the romance, etc.  These involve trickier scripting, so if you have no idea how to do scripts, then I would not recommend trying this sort of thing.

 

Sleep Scripts
All NPCs have scripts which the game checks whenever the party rests.  These are set in the pdialog.2da file, but are generally XXXXXD.bcs, where XXXXX is the name of the NPC.  In order to fire a script at rest, you need merely to put the necessary code to fire a lovetalk into this script.  Use the script that I provided earlier as an example, changing the variables as needed.

In order to do the "Morning After" talks, include PartyRested() into the relevant block of the NPC's primary override script.

 

For example:

(morning after)

IF
 Global("MynpcRomanceActive","GLOBAL",2)
 Global("Lovetalk","LOCALS",19)
 GlobalTimerExpired("MyRomance","GLOBAL)
 PartyRested()
 InParty(Myself)
 See(Player1)
THEN
 RESPONSE #100
  IncrementGlobal("Lovetalk","LOCALS",1)
  Interact(Player1)
END

 

(on rest-add to XXXXXD.bcs)

IF
 Global("MynpcRomanceActive","GLOBAL",2)
 Global("Lovetalk","LOCALS",17)
 InParty(Myself)
 See(Player1)
THEN
 RESPONSE #100
  IncrementGlobal("Lovetalk","LOCALS",1)
  Interact(Player1)
END

 

Randomizing Flirts
To do this, you need to use the RandomNum(x,y) scripting trigger.  See IESDP for more information on this trigger.  You'll put this into the reply line of the Player initiated flirts, or into the GOTO section of the NPC initiated flirts.

An example for Cailean, graciously provided by Kismet:

 

APPEND FWCailej

//Cailean init flirts
IF ~Global("FWCaiDisableFlirts","GLOBAL",0)
See(Player1)
!StateCheck(Player1,STATE_SLEEPING)
CombatCounter(0)
Global("FWCaileanRomanceActive","GLOBAL",1)
Global("FWCaileanStartFlirt","GLOBAL",1)~ THEN BEGIN CaileanInitFlirts
SAY ~I'm going to start a flirt now.~
IF ~~ THEN DO ~IncrementGlobal("FWCaileanRandFlirt","LOCALS",1)~ GOTO CaileanInitHand
IF ~RandomNum(2,1)~ THEN DO ~IncrementGlobal("FWCaileanRandFlirt","LOCALS",1)~ GOTO CaileanInitKiss
IF ~RandomNum(2,2)~ THEN DO ~IncrementGlobal("FWCaileanRandFlirt","LOCALS",1)~ GOTO CaileanInitTickle
END

IF ~~ THEN BEGIN CaileanInitHand
SAY ~(Cailean takes a hold of your hand.)~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN CaileanInitKiss
SAY ~(Cailean gives you a kiss on the cheek.)~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN CaileanInitTickle
SAY ~(Cailean tickles your ribs.)~
IF ~~ THEN EXIT
END

//PC init flirts -- early
IF ~IsGabber(Player1)
CombatCounter(0)
GlobalGT("FWCaiInitLoveTalk","GLOBAL",6)
Global("FWCaileanQuestCompleted","GLOBAL",1)
Global("FWCaileanRomanceActive","GLOBAL",1)~ THEN BEGIN CaiFlirtBaseEarly
SAY ~(Cailean notices your approach.)~
+ ~RandomNum(4,1)~ + ~(Hold Cailean's hand.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + HandHold1
+ ~RandomNum(4,2)~ + ~(Hold Cailean's hand.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + HandHold2
+ ~RandomNum(4,3)~ + ~(Hold Cailean's hand.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + HandHold3
+ ~RandomNum(4,4)~ + ~(Hold Cailean's hand.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + HandHold1

+ ~RandomNum(4,1)~ + ~(Kiss Cailean.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + Kiss1
+ ~RandomNum(4,2)~ + ~(Kiss Cailean.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + Kiss2
+ ~RandomNum(4,3)~ + ~(Kiss Cailean.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + Kiss3
+ ~RandomNum(4,4)~ + ~(Kiss Cailean.)~ DO ~IncrementGlobal("FWCaileanFlirtCount","LOCALS",1)~ + Kiss4
++ ~Cailean, I like you very much, but please don't flirt with me anymore.~ DO ~SetGlobal("FWCaiDisableFlirts","GLOBAL",1)~ EXIT
++ ~(Say nothing.)~ EXIT
END

IF ~~ THEN BEGIN HandHold1
SAY ~Cailean holds your hand 1.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN HandHold2
SAY ~Cailean holds your hand 2.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN HandHold3
SAY ~Cailean holds your hand 3.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss1
SAY ~Cailean kisses you 1.~
= ~It's a really long kiss.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss2
SAY ~Cailean kisses you 2.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss3
SAY ~Cailean asks about the kiss~
++ ~Kiss answer 1.~ + Kiss3_1
++ ~Kiss answer 2.~ + Kiss3_2
++ ~Kiss answer 3.~ + Kiss3_3
END

IF ~~ THEN BEGIN Kiss3_1
SAY ~Cailean kisses you 3_1~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss3_2
SAY ~Cailean kisses you 3_2~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss3_3
SAY ~Cailean kisses you 3_3.~
IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN Kiss4
SAY ~(Cailean kisses you 4.)~
IF ~~ THEN EXIT
END
END

"Death comes swiftly.  FEEL ITS ICY BREATH!"-Sarevok Anchev

Offline berelinde

  • Planewalker
  • *****
  • Posts: 1188
  • Gender: Female
    • Gavin, cleric of Lathander, for Tutu
Re: Romance Authoring Tutorial
« Reply #9 on: January 30, 2010, 03:57:40 PM »
Though I'm contradicting Rastor's tutorial with this advice, I would *strongly* recommend using the J-file for all scripted dialogue, romance talks included.

Putting your scripted dialogue in the J file makes NPC crossmod dilogue trickier later on. Since it's no more work coding it for the J, and may actually be easier, since all you're ever going to have to worry bout is keeping the scripted dialogue ahead of the PID, there is no benefit to putting scripted dialogue in the B. Well, you might flatter modders who are still doing it the old way out of habit, but they probably aren't going to look at your code, anyway.

You have to remember that this tutorial was written years ago, and coding practices have changed. Kulyok posted excelllent advice on scriting dialogue so that it will always run as expected. You can find it here. Rastor's tutorial is generally very good, but it needs a bit of an update.

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: