Example for setting up a typical defensive battle
This explanation was originally posted in a thread where the OP wanted a mod where one faction could fight against the other in some sort of war situation. After trying to explain that Oblivion does not handle this very well, I decided to provide a case which would provide this kind of setup so that they could witness the limitations on AI firsthand.
This example assumes that you have a decent background in using the CS, can use the various editors, know how to make new worldspaces and interiors, and have done some light scripting, NPC creation and quest work. Knowing how to create and use regions for the purpose of setting up weather, generating trees/rocks, or blocking the player from wandering too far away will likely also prove useful.
This is not really so much of a tutorial as something which you can setup and play around with to get a better handle of working with the various elements. The methods described may not be the best way to do these things, but were chosen this way to keep it as simple as possible.
Setting up the factions
A quick note about forms. The forms in this example start with VN5. You are invited to substitute your own sequence as you may be accustom to if you feel you can make all the needed changes to scripts and references as you go along. Just keep in mind that all forms should ALWAYS begin with a letter A-Z, and should not contain any symbols.
If we are limited to only about 10 NPCs or 16 creatures before things become unplayable, the number of possible opponents is already rather small if you are to have anyone other than the player defending. For the sake of keeping things interesting, we'll assume the best balance is, 4 defender NPCs, and 8 attacking creatures. It may be slightly different from these figures, but I believe this will get you the most bang for your efforts. Make the creatures all in the same faction, make this faction flagged with evil and special combat, +100 disposition to members of the same faction, -100 disposition to the defender and player faction (or +100 to player faction if you just want to watch). Make all the creatures have 100 aggressiveness. Make a defender faction that has special combat flagged, and has +100 disposition to itself, +100 disposition to the player, -100 disposition to the creature faction. Make the defenders have an aggression of 10.
For the scene create a new, small worldspace with the buildings in the center, and decorate the surroundings as you see fit. We'll go with a cloudruler temple just because it is a single group of statics which provides the most simplistic arrangement (use a grid snap of 32 to match everything up. The back building piece is called "TestCloudRulerTemp"). You should try to keep the area in front of the gate fairly open, and the terrain behind and around the keep fairly impassable. The total area to be worked with probably shouldn't be larger than 7x8 cells wide (do not use heightmap editor, landscape editor is all you will need). Add trees, and rocks as needed. Make the worldspace have a constant foggy weather (makes it more ominous and removes the need for more terrain (LODs). Create pathgrids in the area in front of the keep, leading through the gate, and around the top of the walls. Do not be concerned with interiors unless you wish to setup the main hall as a sort of ready room or place you can teleport into. Just place load doors everywhere else, do not put in a gate in the front, it shouldn't be needed for our uses. Block off the stable doorway with the kvatch barricades. Place one more of these somewhere on each of the tiers of the stairs, and adjust the pathgrid to move around these.
You have a gate, a first tier of stairs, and a top tier of stairs. Place 2 x markers in each of the guard houses at the front (above the gate), name these VN5Archermarker01 and mn4Archermarker02 place 2 more x markers near the side doors to what would normally be the east and west wings of the keep. Name these VN5Guardmarker01 and VN5guardmarker02. Place 4 more xmarkers a bit of a distance away from the keep, in that open area infront of the doorway. Name these VN5AttackerMarker01 to VN5Arrackermarker04.
Setting up the guards
For the guards, setup 2 of the guards to be primarily melee based, and 2 of the guards to be archer based with some limited ability of melee. Give them default and default archer combat styles accordingly. Make them Savant class, and manually adjust their skills, stats and levels to be suited to their roles. On the melee guards, attach the following script.
ref self short rand
begin ondeath set self to getself set rand to getrandompercent self.resurrect if rand >= 50 self.movetomarker VN5Guardmaker01 else self.movetomarker VN5Guardmaker02 endif end
On the archers, attach the following script.
ref self short rand
begin ondeath set self to getself set rand to getrandompercent self.resurrect if rand >= 50 self.movetomarker VN5Archermaker01 else self.movetomarker VN5Archermaker02 endif end
Place the 4 guards at a starting point around the keep, and give them generic wander packages. As they die, they will respawn were you have those markers before.
Setting up the creatures
For the creatures. You can setup these however you wish, using whatever creatures you wish, you can even use different types, they just have to be creatures. Attach the following script to these;
ref self short rand
begin ondeath set self to getself set rand to getrandompercent self.resurrect if rand >= 76 self.movetomarker VN5AttackerMarker01 elseif rand >=50 self.movetomarker VN5AttackerMarker02 elseif rand >=26 self.movetomarker VN5AttackerMarker04 else self.movetomarker VN5AttackerMarker03 endif end
For their packages, you'll need to make them want to head into the keep so that combat can continue if they aren't already fighting someone. So, inside the walls, around where you have the guards placed, put in an xmarker. Now give each of the creatures a travel package with this reference as the location, and flag "always run" "must reach location". Place 8 creatures outside the gate at a starting location, make all of these persistent references named VN5AttackerCre01 to VN5AttackerCre08. Have them all initially disabled so that you can start the carnage manually when you want, instead if it happening as soon as you enter the area.
Setup the teleport and start spells
Make 2 separate lesser powers with scripts attached to them. The first one will be a spell to move you to the worldspace, or back to Tamriel. The second one will start or reset the fight in the worldspace. For the first one, name it appropriately and attach the following script.
begin scripteffectstart if player.getinworldspace Tamriel == 1 player.movetomarker VN5Guardmarker01 ;; or a marker you have placed within the mainhall elseif player.getinworldspace <yourworldspace> == 1 player.movetomarker ICTalosPlazaCenterNorthSide endif end
This will move you between the worldspaces, and since the location it moves you back to is within the IC, you can't get stuck in a loop from chain casting it.
For the second spell, name it appropriately, and attach the following script.
begin scripteffectstart if VN5AttackerCre01.getdisabled == 1 VN5AttackerCre01.enable VN5AttackerCre02.enable VN5AttackerCre03.enable VN5AttackerCre04.enable VN5AttackerCre05.enable VN5AttackerCre06.enable VN5AttackerCre07.enable VN5AttackerCre08.enable elseif VN5AttackerCre01.getdisabled == 0 VN5AttackerCre01.disable VN5AttackerCre01.movetomarker VN5AttackerMarker03 VN5AttackerCre02.disable VN5AttackerCre02.movetomarker VN5AttackerMarker01 VN5AttackerCre03.disable VN5AttackerCre03.movetomarker VN5AttackerMarker04 VN5AttackerCre04.disable VN5AttackerCre04.movetomarker VN5AttackerMarker02 VN5AttackerCre05.disable VN5AttackerCre05.movetomarker VN5AttackerMarker02 VN5AttackerCre06.disable VN5AttackerCre06.movetomarker VN5AttackerMarker04 VN5AttackerCre07.disable VN5AttackerCre07.movetomarker VN5AttackerMarker03 VN5AttackerCre08.disable VN5AttackerCre08.movetomarker VN5AttackerMarker01 endif end
Then make a startgame enabled quest with stages 0 and 1, and attach the following script.
begin gamemode if getstage <questname> == 0 player.addspell <formID of teleport spell> player.addspell <formID of start spell> setstage <questname> 1 endif end
Provided that everything is done right, and there were no errors (this was all done verbatim without the CS in front of me), you can now test. Even if this is not what you ultimately want, you can probably apply what is used here within your own works. However this should provide a suitable basis to test the concept from since you can add more guards just by placing them, and add more attackers by placing them, making them persistent, giving them a refname, and altering the start spell script to enable/disable them. But as you add more, you'll quickly become aware of the limitations of the game.
I may even decide to post this as an article for others who have similar wants.
*edit* made a few adjustments as I'm going through this myself.
*edit2* If using an interior, it might be prudent to change how the creatures are enabled/disabled using a variable in a quest script which is changed to 0 when the door is used, and is toggled between 0 and 1 with the spell. The quest script can then do the enable/disable (in a gamemode block) instead of the spell, allowing the door to work as a failsafe. You can pair this with scripting in the creature scripts so that each creature enables/disables itself based on this variable, removing the need to amend the scripts to add more creatures. This is a bit more complicated, and assumes that scripts still run on disabled creatures, but should allow for a bit more functionality for a more diverse situation.
I may decide to upload partial versions of this for review in the future using different starting characters so that the forms don't conflict if you used the exact ones given.