OldMansBeard's Henchman System
Module Builders' Guide
Version 1.3
2005-03-09
Introduction
You are a module author. You have spent many long hours contriving play balance and matching encounter difficulties to combinations of player classes and levels. You have added your own carefully-crafted henchmen and woven them into the plot. Now, the OHS comes along and allows players to walk all over it by calling in effectively limitless henchman power. How do you stand?
-
1. [Shrugs shoulders] If that's what they want to do, fine. If it works, it works. If it doesn't, it doesn't. I've done my bit. If they want a diminished challenge, that's their problem.
-
2. [Thumps table] No. I can't allow this. How can I disable your wretched henchmen?
-
3. [Scratches head] Interesting. I can live with this. But on a technical level, how can I script modules so that I can control the balance and avoid incompatibilities?
-
4. [Does victory dance] Great! How can I incorporate it into my module?
Disabling the OHS
The simplest and most certain way is to include a script called default in your module. It doesn't have to do anything, just void main(){} is quite sufficient. That will kill the OHS system stone dead.
Another way is to do a SetLocalInt(GetModule(),"OHS_SYSTEM_DISABLED",TRUE); somewhere in your OnModuleLoad script. This will ensure that any imported henchmen who do creep in will just stand around like useless dummies. Setting and clearing this flag in different areas can also be used to limit the parts of your module that imported henchmen are allowed into and through - if you want to ensure that the PC is on his own in plot-critical encounters, for example.
Living with the OHS
1. Filename Compatibility
All of the dialogues and all bar two of the scripts in the OHS have names beginning with the prefix ohs_. Avoid using this prefix yourself if you can. The only scripts that do not use this prefix are default and nw_g0_conversat.
PCs and copies of PCs are created by the Bioware engine with "default" hard-coded as the script name in each and every event handler slot except OnConversation, which goes to nw_g0_conversat. In the normal game there is no script called "default" and, although these objects receive event signals, the signals evoke no scripted response. In the OHS system, however, there is an actual script called default to respond to the event signals received by henchmen and thereby give them behavior. If you need a default script for your own purposes, have a look at mine and see if you can adapt it to suit.
The system overrides the standard Bioware nw_g0_conversat and uses it to assign a dialogue file explicitly to henchman objects. Again, if you need a custom one, see if you can adapt mine.
2. Templates
The system includes templates for three items and two creatures. These are put into the standard palettes, not the custom ones. This is a bit unusual but it is done to avoid any possible conflict with templates you create in the toolset, import from ERFs or take from hakpaks. Carry on as normal and there shouldn't be a problem.
3. Script Compatibility
When writing OnEnter/OnExit scripts for areas, triggers and the like, remember to expect extraneous NPCs to be going through and possibly setting them off too many times. The linkboy and OHS henchmen are scripted to follow their masters fairly relentlessly (even through secret doors!) so there shouldn't be a problem with movement generally unless you do something fairly strange.
4. Henchmen
If your scenario includes your own special henchmen, don't assume they will necessarily always be at the top of the GetHenchman() list and don't rely on GetMaxHenchmen() having any particular value. If you do a SetMaxHenchmen() in your OnModuleLoad event or wherever it will take effect initially but will be raised ad hoc to accomodate the linkboy and OHS henchmen as they are hired.
The OHS henchmen use their own, slightly modified versions of the standard x0_ch_hen_* scripts for their behavior. If you modify the standard ones for any reason, the OHS henchmen's behavior should be unaffected. The intention is that they should seem to be "the same people" in all modules, regardless of any special behavior given to module-specific NPCs.
5. Module Transitions
If you are writing a series and using StartNewModule() to transport the PC from chapter to chapter, you may or may not want to transport your own henchmen with them.
The system used in SoU and HotU, using database files to copy henchmen across, works well the way Bioware use it. Indeed, even OHS henchmen get carried along through the transition from Chapter1 to Chapter2 in HotU. But there is one thing to watch out for. If you save henchmen while they are hired and restore them into another module, their faction id will no longer be valid unless the faction table for the new module happens to have the same number of entries as the one in the old one. Henchmen with the wrong faction id will still be henchmen but they won't appear in the right hand column on the screen, won't hear shouts, may not support their master in combat and may even be hostile. The function FixFactions() in ohs_i0_commands.nss attempts to correct this and is automatically called by the PC at the first appropriate moment.
The expectation is that players will use the OHS KEEP/OHS RECALL commands before and after module transitions and re-hire their henchmen when they re-appear. It helps if you warn the players when a transition is imminent.
6. Cutscenes
Cutscenes can cause problems if there are extra NPCs around you hadn't bargained on. The linkboy and OHS henchmen are scripted to stay out of sight in cutscenes but I can't guarantee the scripting is 100% watertight.
If you need to distinguish them in scripting, it may help to know that all linkboys have the tag "OHS_LINKBOY" and all OHS henchmen have tags beginning "OHS_HEN_" followed by their full name (with capitalization preserved and spaces omitted).
7. Controlling Equipment and Levels
A player with many henchmen will have a hard time keeping them all suitably equipped as they rise in levels, especially if you are fairly sparing with treasure and merchants. Bear in mind, however, that the OHS allows henchmen to be imported who may already have been lavishly equipped in some other module over which you have no control. Players can't loot their henchmen for such goodies but the henchman themselves may be too powerful nevertheless.
A popular device is to strip the entering PC of levels and equipment at the start. This will help to control levels because PCs can only hire OHS henchmen with fewer XP than their own but it doesn't prevent a player calling in a cunningly-prepared Level-1 henchman decorated like a Christmas tree with +20 equipment. You might consider introducing a roving band of robbers to redress the balance!
8. Factions
The OHS henchmen belong to the "Merchant" faction when created and revert to it when dropped or otherwise unhired. Strange things may happen if this faction is redefined or even removed from the faction table in a module.
9. Encounter Scaling
Finally, it helps if you can make your encounters scale. If you are writing for multiplayer, you are probably there already.
Random encounters made with the Encounter Wizard in the Toolset do scale to take account of henchmen, including OHS henchmen, although they are limited to 8 creatures so you may want to include some tougher creatures to balance stronger parties than you might otherwise have done.
Set-piece encounters with arch-villains generally don't work this way but you might consider doing a LevelUpHenchman() on the villain(s) to balance up the GetHitDice() total for the player party to help make it a fair fight.
Incorporating OHS into your module
Firstly, familiarize yourself with all of the foregoing. Then, if you are still happy to work with OHS you have two options:
-
Advertise your module as compatible with OHS and simply tell players where to download it.
-
Embed OHS into your module.
You are welcome to embed the system, though I would appreciate an acknowledgement!
The simplest way to embed is to create a hakpak containing all of the files from the override folder of the OHS distribution except the two *palstd.itp files, and attach it to your module.
Alternatively, if you have an editor that can create erf files, you could put all the files into an erf and import them into your module. In this case you will need to edit the "Torch, Red" item template in the Miscellaneous/Other palette and set its appearance to iit_torch_000.
If you want to place a henchman in your module who will behave like an OHS one, make a first level character and give it a tag of "OHS_HEN_"+FullNameWithSpacesOmitted. Leave its conversation slot blank, set the OnConversation script to nw_g0_conversat and all other scripts to the word default.
You can change an OHS henchman's conversation dynamically by scripting by setting a local string variable "OHS_DIALOGUE" on it to the name of your alternative dialogue file. This will be picked up by nw_g0_conversat and used in place of ohs_henchman.dlg.
If you want to customize the system for your module, feel free. But you need to know what you are doing. If in doubt, ask!
About the linkboy
Don't be tempted to eliminate the linkboy and expect things still to work. On the surface, as seen by players, he seems no more than a torch-carrier and messenger boy, maybe only needed occasionally and perhaps dispensible. But underneath he is continually doing three things that are each vital.
-
He is continually clocking the henchmen's heartbeats. If he wasn't there to do that, they would stand around like dummies doing nothing each round.
-
It is the linkboy who listens out for the OHS commands and interprets them. Players only need them occasionally, but if you think about it, there has to be someone listening out for them all the time in case they do. It's him.
-
He also keeps the henchmen in formation behind the player. If he stopped doing it, there would be chaos going on back there as all the henchmen collided with each other in their eagerness to follow-my-master. This would cause an untenable performance hit as the engine fell into loops failing to cope with the resulting collisions. Believe me, I've seen it. It's grim.
The two scripts that do most of this are ohs_lb_heart and ohs_lb_onconv. Adding extra commands in ohs_lb_onconv should be fairly safe, if you want to try that. You will need to prepare the listening patterns in ohs_lb_spawn, of course.
Henchman AI and the default script
The main job of the default script is to sort out event handling and call the individual ohs_hen_* scripts when appropriate. They in turn bottom out in the Bioware include files that provide the AI for the henchmen. If you want to experiment with modified AI schemes, this is the place to start work. The best advice I can give is to design thoughtfully, code in tiny increments, test heavily and get a buddy to check your work. But you know all that, anyway.
A Toolkit of Scripting Functions
An include file of scripting functions called ohs_i0_toolkit.nss has been provided. If you read the declaration part of the file, it should be self-evident what the functions are for and what they do. If not, feel free to post in the OHS Henchman Guild. There is a link to the Guild in the OHS_README.html file.
Very briefly, a Companion is a playable henchman who accompanies a Hero and a Hero is the result of playing one as a PC. These characters are not registered in the Registar's database but are "owned by" their players.
Embedding the "Way of Heroes" areas
There is no real need to embed the Registry Office - all it contains is the Tobias figure and players can call him into play at any time anyway. If you want to embed the Temple of Ohum area (by exporting the area from the module and importing it into your own) there is just one thing to think about: in the module, there is a script attached to the OnUnAcquireItem event that vanishes any items dropped by a PC. This is so that players can't trivially double their gold and equipment by dropping it all on the floor, doing the Ritual to get another copy and picking it all up again. One solution would be to take the ohs_ev_unacquire script from the module and specialize it to only apply in the Temple area or thereabouts. The functioning of the Temple Rituals does not depend on this event so you can decide independently whether to worry about it or not.
The "End of Rest" dialogue
In the present version (1.3) this dialogue (ohs_group.dlg) is a placeholder for future development. The intention is to make it progressively more interesting by introducing different personalities for different companions and relevant topics of conversation. By all means elaborate the dialogue if you wish, but try not to "lock out" future updates to this file. Your players might miss out on some "good stuff" to come.
Have fun.