Rune is a third person action, combat, and adventure games with strong themes from Norse mythology. You play a young Viking trying to uncover the mysteries around recent attacks on your village. The game is played from third person perspective to make the melee combat with a huge variety of weapons more fun, as well as giving you a chance to fully appreciate and explore the complex world.

Post tutorial Report RSS Major Additions to RuneEd

Written by Dave Halsted, a level designer at Human Head Studios.Following is an extensive reference list of additions we have made to UnrealEd with Rune. This reference is designed primarily for level designers who are familiar with making single-player or multi-player maps for Unreal or Unreal Tournament.

Posted by on - Advanced Mapping/Technical

Originally posted here: Originally posted on Runegame.com by Dave Halsted

Mirrored for archival purposes

Hello there, boys and girls. Following is an extensive reference list of additions we have made to UnrealEd with Rune. This reference is designed primarily for level designers who are familiar with making single-player or multi-player maps for Unreal or Unreal Tournament.

As a tutorial, it is fairly bare bones, but there's a lot of material to cover and this is the best way for me to start. It covers everything I can imagine, but of course I'm sure I've missed something. Please contact me to report errors/inconsistencies/gaps in this document, or if something is too unclear. But only contact me for those reasons.

In time, I may make some simple tutorials, mostly for scripting techniques, but please don't swamp me for map-making tips. There are many good tutorials out there for editing in UnrealEd that will get you making rooms, lighting them, texturing them, the whole nine yards. When you're up to speed, refer to this document for information of Rune-specific additions/changes.

Dave Halsted

First Things First
To make a map run for deathmatch, here is what you need to do:

1. Set down as many NavigationPoint->PlayerStart's as you need; these are your spawn points.

2. Under the Options menu, load up the Level Properties window and go to the LevelInfo category. Now, under the Classes menu on the right side of the screen go to Info->GameInfo->RuneGameInfo->RuneMultiplayer. Select this so that it is the highlighted class. Now go to the LevelInfo window and under DefaultGameType, hit "use" and all that RuneGameInfo/etc. wackiness will be printed in there for you.

3. You can type in author and all that other good stuff if you'd like, and screenshot importing is the same as in UT.

You can change respawn times on the weapons and Runes under their individual Inventory->RespawnTime properties. That's all you need.

Note that when making a Single Player map, there are separate RuneGameInfo's for each of the various costumes Ragnar has throughout the game, so you'll want to pick a costume and put that particular singleplayerinfo in the LevelInfo slot. Otherwise you'll start as default LeatherRagnar.

Interface
When you right-click a surface to add an actor, you can now choose "Add X at camera point". This is extremely handy. Whatever you place will be located right where you are in space and aimed right in the direction where you're looking. This was indespensible for setting up spotlights, directional ActorGenerators for rockfalls, as well as Interpolation points and CineInterpolationPoints for flight paths and cinematics.

In each of the four windows, you can now choose "Polygon View". This will render the world in three colors; Green denotes walkable surfaces, and Red and Blue denote non-walkable surfaces. Also, this view and now the Zone/Portal View are rendered with black lines along the edges of polygons, aiding much in visibility and building.

In each of those four windows, as well, you can turn on Crosshairs, a Spline view, as well as Event lines to help you see who's calling whom in the events chain.

In the Rebuild Window (F8 calls it up), you can now set it so that hitting Rebuild Geometry doesn't necessarily then rebuild the BSP and Apply Lights. In my configuration I keep Apply Lights separate (via the checkboxes at the window's bottom) to save time on larger maps. Under the Lights sub-menu, you can select "Apply Lights in Selected Zones Only". This is useful as well on huge maps with tons of lights and zones, where you don't necessarily need RuneEd to do the light pass on the entire level when you're just working on the lighting in one small bit. If this is highlighted, RuneEd will only apply lights in zones whose ZoneInfo(s) have been selected in one of the four views.

Much like Autoplay in Unreal, RuneEd now saves out an AutoBuild.run file. This is saved out every time you rebuild geometry or apply lights. The editor saves the current state of the map and then peforms the rebuild or light application. It's a very useful failsafe and can really save your butt if you crash having not recently saved.

You can now build sheets that match a selected world poly/surface that you highlight in the 3D view. You must first bind a key (under Advanced Options) to this command:

brush sheetfromselected

Now, when you select a surface(s), and hit this key, you'll get a sheet that matches. Very handy for making water sheets and all sorts of other strange things [the bright blue 'ice' patch in underwater start of Mountain1 was painstakingly made this way and then added as a visible, transparent Zone Portal].

2D Shape Editor

This has been made much more stable. Note that on some systems that minimizing the Editor or pulling the window resize bars will still crash RuneEd if you have the 2D Shape Editor open.

You can zoom in and out of the 2D editor endlessly now. You can also have multiple shapes up in the 2D editor at once, which is handy for setting up breakable walls and the like. You use "New Segment" and "Delete Segment" to manage this.

New points on a shape can be inserted as before, but you can also "pull out" a new point by selecting an edge, holding "CTRL", and clicking out away from it - a new point will be drawn from that edge out to where you want - very handy for efficiently making complicated shapes.

There is a bug where sometimes that new point will not be perfectly on the grid, however, this is remedied by pulling it around and then putting it back where you wanted it, so it's no big deal.

Under "Bevel", you can now deselect "Constrain Proportions" and bevel with uneven dimensions. The caveat to this, though it gives you cool-looking organic shapes, is that it has to build the bevel using triangles, and not 4-sided polys.

This means you get more polys in the view and potential problems with stability and holes, since Ed doesn't like it when you start getting fancy with triangle-based mesh shapes. Handy nonetheless, though. When doing unconstrained bevels, "Convex" and "Concave" define whether the nature of that uneven bevel is 'curved' inward or outward... subtle difference and not a big deal.

A limitation with Unreal's "Extrude" was that it was just a straight extrude. If you wanted to skew it you'd have to manually pull all the points on one end across on the map. Now, by selecting the "Sheer" checkbox under the Extrude window, you can do this automatically.

The angle and severity of this skew is defined by the currently selected "point" on the 2D shape you've got (it's drawn with a little yellow circle) and the green (yellow?) center point that is always in the middle of the 2D Shape Editor. As it extrudes it will shift over as if to bring that yellow point to the same position as that center point, skewing the extrude in the process.

Triggers

Dispatcher: The dispatcher can now be set to loop forever through its actions. This does not run automatically; the Dispatcher has to be triggered to get it going.

DispatcherFaucet: This is a custom Dispatcher. It works off of Unreal's Trigger/Untrigger stuff. When you are in the collision radius of a standard, default-setting Trigger who's Event is the DispatcherFaucet, the DispatcherFaucet will run continuously (if set to IsLooping->TRUE). As soon as the player steps out of that Trigger's radius, the DispatcherFaucet will turn 'off'. I used these in Mountain1 for that big rock fall area. I didn't want all those rocks falling at once and melting the frame rate, so they're set up in separate DispatcherFaucet 'systems' each run by its own large proximity Trigger. That way the rocks are only ever falling in the part of the map where Ragnar is, and hence better frame rate.

OrdersDispatcher: Never used 'em! So I don't have much to say about them.

RandomDispatcher: If Dispatcher->AutoStart is set to False, it will not run until it is triggered. If the RandomDispatcher is set to IsLooping->TRUE, then the ContiguousEvents category is irrelevant. However, if IsLooping is set to False, ContiguousEvents tells the RandomDispatcher how many events to pump out each time it is triggered. RandomDelayMin and RandomDelayMax set the range for the time delay between each random event; but if a randomly chosen Event has its own Delay greater than zero, then that delay will also occur when it is activated. Basically you've got eight slots for events and each has its own probability. Very nice for setting up ambient environmental effects.

CineTrigger/DamageTrigger/DestroyTrigger/etc.: We never used these, prefering to do all these things through SpecialEventRune's.

Lever and Pump: They have all the settings and functionality of a normal Trigger, but are custom-code visible actors as well with their own built-in sounds.

SightTrigger: Works like a normal Trigger, except it is activated when the player looks in its direction. I'd avoid using it for anything critical and use it simply to set up little ambient scripted events.

Don't bother with ZoneTrigger and ZoneVelocityTrigger. Instead the ZoneTemplateTrigger has everything you need...

ZoneTemplateTrigger: This one is really useful, as it lets you change things about a zone on the fly, like turning fog, water, and pain settings on and off as well as changing things like velocity. Under its ZoneTemplateTrigger property category, you'll find the bulk of settings that you normally see in a ZoneInfo. When the ZoneTemplateTrigger is triggered by some event in the game, it will impose its Zone properties on to the ZoneInfo named under ZoneTemplateTrigger->Event.

Some changes are a little quirky. For instance, to turn on "pain", the target ZoneInfo must be set to bPainZone->TRUE with a PainAmount of zero. Then the ZoneTemplateTrigger changes this Pain amount to whatever amount of damage you'd like. If the ZoneInfo is initially set to bPainZone->FALSE, then a ZoneTemplateTrigger will not be able to change this property.


SpecialEventRune (SER): This is a greatly expanded version Unreal's original SpecialEvent. Under the SER's Object->InitialState you choose which of a number of functions you would like it to perform when it is triggered.

Here are some of the more commonly-used ones. To make these work on Ragnar, type in "Player" [not "Ragnar"] under ObjectTag.

PushObject: There is a PushObject property that lets you type in a vector. This force will be applied to whatever actor is tagged under SpecialEvent->ObjectTag. To push pawns like the Player around, you need a fairly large vector.

ObjectHateOther: The pawn called in SE->ObjectTag will immediately want to kill the pawn typed in under SER->OtherTag. This is not 100% - sometimes if the pawn has already seen Ragnar and wants to kill him, he will continue to come after Ragnar and not follow the HateOrder. To make two guys fight each other, you a pair of SER's to tell each to hate the other.

OrderObject: When this SER is called, the SE->ObjectTag Pawn will immediately go to the ScriptAction/ScriptPoint/ScriptDispatcher called under SE->ScriptTag. As always, if it's a ScriptPoint the Pawn will physically walk to, whereas a ScriptAction will be called immediately. See the Scripting category in this document for more on this.

DestroyObject: When this is called, the actor under SE->ObjectTag will be immediately removed from the world. No fancy explosion or anything, it'll just be gone. This could be a Pawn, something like a Dispatcher, anything. Quite useful when setting up complicated scripting where there are multiple outcomes depending on the player's actions.


UseObject: We used this a lot to make it look like enemy creatures were "using" Levers, Pumps, and such. It has the same effect on its SE->ObjectTag as the player physically walking over to the object and hitting their "Use" key.

Quake: Makes the screen shake with an earthquake effect. There is a special Quake property that contains the self-explanatory settings.

DamageObject: This does X amount of "hit point" damage to the SE->ObjectTag. The damage amount is under SE->Damage. If you want to make an actor "catch fire", set the SE->DamageType to "Fire".

Let's say you want to have a big breakable wall as part of some scripted event. You'd set it up as a Polyobject (see the Polyobject section for more on this), and give that PolyObject a nice high DamageThreshold like 10000, to ensure that the player wouldn't be able to break it even if he whacked on it for two hours. Then, when you want it blown up, you'd call an SER who's Object->InitialState was set to DamageObject, and deliver the necessary 10000 points of damage. Voila! The sucker will blow up with all its nice debris and damage effects and sounds.

KillObject: This kills the Pawn, including "Player", under SE->ObjectTag. The Pawn will fall over dead and make his gasping sounds, etc.

Keypoint


ScriptAction: I'll cover this one under the Scripting section.

ScriptDispatcher: I never used these, but they appear to have a couple unique scripting properties and are a good way to put a lot of scripting information into one actor icon [Look at the ScriptAction arrays in SailingShip for an example of where I should have used the ScriptDispatchers for the sake of visual cleanliness].

LookTarget: These are a good way to focus the player's attention, as Ragnar will turn his head to look at these, and they take priority over normal look targets like items and enemies. You can turn them on or off by calling the name Tag that you give them.

ActorGenerator: This is the big one, and we used these for many different things ranging from spawning in enemies to spawning in rockfalls, etc. In one case I used an ActorGenerator to spawn in Counters.

There are a lot of options under these guys, so I'm just going to haphazardly tear into it here.

If you go to the ActorGenerators Properties, there are a bunch of options under the category "ActorGenerator".

ActorClass: This is where you put in the name of the actor you want spawned. You do this in the standard Unreal manner of selecting the actor in the Classes menu and then clicking "use" in four ActorClass slots.

ActorProbability: Pretty self-explanatory. Just make sure it's not "zero" or it won't spawn. You can type in any sort of values that you like; if there are more than one, the engine will average them out. So it's the relative scale that matters when weighting out the odds, not the specific numbers used.

bInitiallyActive: if this is left at its default of FALSE, you need to trigger the name of the actorgenerator to set it off.

bMoveWhenUnreachable: This only applies to enemy Pawns when you're spawning them in. By default, Pawns will not roam around the map or hunt Ragnar if he is in an area they can't get to (like a ledge he edge-grabbed to, etc.), and is done for the sake of processor efficiency. If you set this to TRUE, the Actorgenerated Pawns will always try to get to Ragnar, even if they can't. It's a case-by-case thing, but the less you use it, the better your performance will be. [Watch for the "Move" time in the Global stats - if it's skyrocketing, you'd better 'dumb' some enemies down by disabling this]

bRandomPosition: If set to TRUE, the actor(s) will spawn in random locations, based on the ActorGenerator's CollisionHeight and CollisionRadius. [In all cases, the spawned actor(s) take the ActorGenerator's direction.]

bSpawnWithNoShield/bSpawnWithNoWeapon: These pertain to spawning enemy pawns and are self-explanatory.


bTriggerCreations: If this is set to TRUE, then the actorgenerator will "call" the actors immediately after spawning them. We needed this in the case of the rockfalls throughout the game. In those cases, we were ActorGenerating RockLarge, RockHuge, RockMedium, etc. [located under Decorations in the Classes menu], and those actors have special physics code so that they fall naturally, bounce, etc. But they don't do all that nice physics stuff if they aren't Triggered, so in the case of them you need to have bTriggerCreations->TRUE. Probably not too useful for anything else, so the default is FALSE.

DelayAlways/DelayRandom/DelayType: These three work in conjuction for timing when you're ActorGenerating a whole bunch of things at once. DelayAlways is the minimum delay between each spawn, while DelayRandom is a random amount of time that gets added to that. For instance, if the ActorGenerator was set to spawn in 10 crows over time, and DelayAlways was 2 (seconds) while DelayRandom was 3, there would be a minimum of 2 seconds and a maximum of 5 seconds of time between the spawning of each of the 10 crows. DelayType weights this. If DelayType for the 10 crows were set to "Increasing", for instance, the first would spawn with a larger gap (again, between 2 and 5 seconds), and by the end there would be pretty much only 2 seconds between the spawning of the final couple crows.

DirectionWeight/DirectionWeightRandom: setting a DirectionWeight will cause the spawned actor to 'spit out' in the direction of the ActorGenerator's direction arrow. DirectionWeightRandom is a random amount that is added to this when you want variety. We didn't use DirectionWeight much; I found it to be a little quirky, but that was long ago and I don't quite recall.

QuantityAlways/QuantityRandom: If you're just spawning in one enemy, set QuantityAlways to 1 and QuantityRandom to zero. Otherwise, it works along the same lines: If QAlways it 5 and QRandom is 2, you'll get between 5 and 7 of whatever you're spawning in.

SpawnOrders/SpawnAlertOrders/SpawnTriggerOrders: These allow you to spawn in a Pawn with all the Orders functionality that you would have if you'd placed him in the editor. See the "Scripting" section of this document for an explanation of how these three-order types work.

SpawnWithEvent: This works as advertised - it gives whatever you're spawning an event. So if you want the opening of a door triggered by a creature's death, ActorGenerate that creature with the door's Tag as the creature's Event that it spawns with.


SpawnWithHealth: No-brainer. When left at zero you get the creature's default.

SpawnWithTag: This lets you give a specific Tag name to creatures you spawn, therefore allowing you to Order them to do Scripting at some point after they've been spawned.

SpawnWithWeapon/SpawnWithSheild: If left as is, the creature will spawn with its standard weaponry. To put the name of a weapon or shield in these slots, highlight the weapon/shield in the Classes menu and select "use" under the property slot.

SpawnWithHuntDistance: HuntDistance defines how far the creature will roam - it's basically a tethering distance between the creature and the place where it was spawned. But it's got some problems and we made sure that is was disabled for all ActorGenerators in Rune.

So that's the almighty ActorGenerator for you. I'll go into some detail on the process of making convincing rockfalls:

What you want to do is put the four sizes of rock in the four ActorClass slots, and then balance the ActorProbabilities as you'd like (most smaller or medium, most large...?). There are two types of rock, both located under Decoration:

RockHuge/RockLarge/RockMedium/RockSmall: These four will hurt the player (maybe Small and even Medium don't...? not sure), and will bounce off walls and land on the ground. That last phrase sounded idiotically unnecessary, but there's a reason! Because...

RockAvalancheHuge/Large/Medium/Small: These four work the exact same as normal rocks, but they explode whenever they hit any kind of surface. In other words, if you're worried about tons of Rock actors piling up on screen and melting the framerate, use these Avalanche ones because you get all the functionality gameplay-wise but no big actor build-up (though the shard particles are a momentary hit, so use your discretion).

Then it's just a matter of setting up your bRandomPosition area, the total number of rocks, and the timing. And remember that the ActorGenerator is not a one-shot tool - you can keep calling it all day long whenever you want it to spit out your swarm of crows, avalanche, bad guy, or whatever.


SoundPlayer: These are a real godsend and can be made to work in many different ways.

Under their "Sound" Property are the settings for setting up continuous, looping ambient sounds. There's no better example of how to do this well than by looking at the work out sound guy did on our levels when he made his ambient sound passes. By subtly varying pitch and volume of even the same looping sound file and then overlapping the radii of multiple sound players playing it, you can achieve some very realistic environmental effects. Note that just about all actors in Rune can play an ambient sound - even lights have a slot for it now. But for the sake of sanity I'd stick with using SoundPlayers so you get that easily recognizeable icon.

"SoundPlayer" Property: This is where all the good stuff is.

AutoContinuous: If set to FALSE, the SoundPlayer will only play its sounds each time it is triggered. If set to TRUE, the SoundPlayer will continously play the sounds in its sound slots based on their probabilities, the random and minimum delays, etc.

bPlayerSound: If set to FALSE, the sound will emanate from the SoundPlayer's location in the world. If set to TRUE, the sound will play off of Ragnar. This was used for points where theme music or "aha!" music was played, and it means the volume stays consistent as the player moves around.

bRandomPosition: If set to TRUE, the sound(s) will play from a random location within the space defined RndPositionHeight and RndPositionRadius.

RandomDelayMax/Min/RandomPercentPitch/Volume: These tend to pertain to when you want the SoundPlayer to autoContinuously play some environmental sounds. For instance, maybe you have 4 different non-looping animal sounds that you want to play throughout an area. You could give that SoundPlayer a nice big random radius that covers the general area, and set it to bAutoContinuous->TRUE. These 4 properties that we're on to now let you adjust the timing/randomness of those animal sounds' playback. RandomDelayMin and Max define the range of time between each sound being played (chosen by the SoundPlayer from its TSound list and probabilities), whereas RandomPercentPitch and Volume add randomness to the sounds so that they don't always sound identical. In these cases, our sound guy would recommend not going too crazy with the RandomPitch and Volume. The scenario you want to avoid is the sound by chance randomly playing right where the camera is with some crazy 150% volume blasting in the player's speakers.

Aside from playing a looping ambient sound (which, incidentally, all have an "L" at the end of their name in the Sounds menu so you can tell at a glance) through the Sound property and setting up a looping system of non-looping environment sounds, as described in the preceding paragraph, the other major use of SoundPlayers is as a triggerable sound source. In these cases (like playing a theme song when a battle starts or playing an explosion sound during a big scripted crash), you'll want to turn bAutoContinuous to FALSE and muck with these settings:

TSound: This is where you insert the name of a sound file that you have highlighted under the Sounds menu.

TSoundProbability: Here you give the odds of playback if you have multiple sounds you want called randomly.

TSoundPitch: You can change each of the 4 sounds' pitches here. Not that RandomPercentPitch will work its variation off of this number, as it should.

TSoundVolume: Ditto.

To set up the SoundPlayer so that it plays a sound back when triggered, you need to do these things:

TriggerBehavior: Set it to "Single" if you want one sound played each time the SoundPlayer is called. As far as Continuous and ContinuousOnOff are concerned, I can't vouch that they work as advertised, but the idea is this: if it's set to "Continuous", then once the SoundPlayer is called it'll start cranking out sounds from the TSound slots all day long, with frequency based on the RandomMin and Max. If it's set to "ContinuousOnOff", it'll do this as well but will turn silent again if the SoundPlayer gets triggered a second time.

SelectMode: Let's say you're planning on calling the SoundPlayer multiple times, and you have more than one sound in the TSound slots. If SelectMode is set to "Cycle", you'll get the same order of sounds each time, starting with whatever's in slot "0" the first time it's called. If SelectMode is set to "Random", you'll get a random sound based on the probabilities you set up.

TriggerCountdown: If this is left to its default of zero, you can just keep calling the SoundPlayer again and again all day and you'll get a sound played back every time. But if you put a value in here, the SoundPlayer will effectively disable itself after that many calls. So if it's set 3, the fourth and subsequent times you call the SoundPlayer you won't hear jack.

Zone Info


bTakeOverCamera: if set to TRUE, then the camera sits wherever the ZoneInfo is located whenever the player is inside that zone. The camera returns to normal 3rd-person when the player leaves the zone.

ZonePlayerExitEvent: an expansion of the ZonePlayerEvent (upon entering) that Unreal already had. It fires when the player leaves the zone.

SkyZoneName: You can now have multiple skyboxes in a level, which is pretty damn cool. The only thing is I didn't get a chance to use it, so I'm not sure how it's done, but I'd guess here is where you type in the Tag for the specific SkyZoneInfo you want referenced as the skybox in each particular zone, where applicable.

bFogZone: You still need to set this true if you want to use Unreal's fog balls, but it also applies to the new distance fog we added for Rune. Note that having distance fog and the old Unreal volumetric fog in the same area causes rendering problems, so make sure any fog ball's radius is outside of a distance fog zone.

bFarClipZone: The great clipping plane! Hoo haw! If set to TRUE, then Unreal does not render geometry that is 'behind' the distance fog. Unnoticeable to the player because those areas are solid fog color anyhow, but a great performance gain as far as poly counts are concerned. It occludes actors as well as geometry.

Under ZoneLight are the settings for distance fog: Brighness/Distance/Hue/Saturation.

There are a couple new types of ZoneInfo. CloudZone is used for big death pits where the player should automatically die, etc. ShredderZone makes the zone such that any actor entering it is immediately destroyed. Not with any explosions or fanfare, but Destroyed in the "programmer" sense in that it is immediately removed from the world. The Zombies that are spawned and marching continuously behind the grate walls in Hel3b are marching right into an out-of-view ShredderZone, and the rocks falling in ThorApproach land in a ShredderZone way at the bottom out of the player's view.

Lights

Don't know if this was in Unreal, but you can choose whether a light affects the world, actors, or both.

There are now 3 Special Light categories for a total of four. These correspond with the SpecialLit1/2/3 check boxes that are now in the Surface Properties menu.

bNegativeLight: This one is fantastic. It makes the light 'negative'. It's great for creating shadows and such, and it's also great when used subtle to break up the hue and brightness of a large texture surface. Note that it is 'negative' in all sense, and the Hue will be backwards from what you're used to. So if your room is lit with a hue hovering around 140, and you put a negative light on there, you'll need to tweak the negative lights hue a bit to find what value makes it cast darkness of the same bluish hue as the room. An interesting side-effect of negative lights that I didn't have time to exploit is that they will override an area's Ambient light and can therefore create a 'dark' area darker than anywhere else in the zone.

There are some caveats: you probably want to avoid doing anything too major or critical with negative lights, as they will look different on different video/machine configurations. Also, if the player jacks up their screen brightness, areas that you've "super-blasted" with negative lights will stick out and look weird - those parts will appear strangely "too dark". But as long as you stick to the subtler side with them, the possibilities are quite great, particularly combined with the various strobe and cloud cast-type effects and such built into Unreal.

Ropes and Spewers

There are a ton of different particle system classes that we added, but most are pretty self-explanatory. The main thing with them is to experiment with the default settings... and make them look as good as you can without using many particles, since they can be a big performance hit if you get too silly with them.

But our implementation of Ropes could use some explaining. It's a little confusing and unfortunately less unified than we'd like, but there are a couple different types of "rope" in Rune and they all work a little differently:

"HangingChains" are decorative and have cool physics, but you can't climb them - though you can attach something to them, like a 'dead guy'. In Rune I believe we had HangingChains holding skulls, and some holding dead guys. It can be a little fishy getting them all set up right... our programmers gave us some default ones that we just exported/imported into our own maps to save time.

Under ParticleSystem->BeamSystem, you'll find BeamChain, BeamRope, and BeamVine. They will draw a non-climbable visual Rope/etc. to whatever target location you give them (under the property BeamSystem->TargetTag). If the target moves around, the rope will automatically draw to it as it goes for a cool effect.

Under ParticleSystem->BeamSystem->Rope you'll find ClimbableChain and ClimbableVine. These are the ones in the game that have an ambient sway and can be climbed. You can adjust their height using the Collision->CollisionHeight property.

The ClimbableChain and ClimbableVine appear in the editor as a rectangular, yellow icon, which stands at the rope's "center". The BeamChain/etc. appear as the blue "particle".

Spewers are extremely handy for setting up timed fire pits, steam blasts, and the like. You can also control the degree to which they damage the player, if at all. You'll find it at ParticleSystem->Spewer->FireSpewer. The SteamSpewer should be good to go, as well - but I'd avoid the MechFireSpewer. We used FireSpewers and SteamSpewers exclusively. They don't have to shoot fire or steam. Under the Spewer's ParticleSystem->ParticleTexture slot, you can put it whatever particle texture you'd like. The bubbles that shoot out when the Vikings 'splash' into the water in SailingShip were done using non-damaging FireSpewers pumping out the Bubble texture that's in RuneFX.utx, and the natural effect was achieved by tweaking the Spewer's velocity settings and ZoneVelocityScale. But on to the more commonly needed FireSpewer settings:

The basic way the FireSpewer operates is that is has an "on" time, and an "off" time, and it cycles between them. You can use them for precise timings or for more random, ambient timings. If they are set to do damage, the damage is applied only when the Spewer is fully on, not when it is either building up or shrinking down in its cycle.

ActiveDurationMax/Min: The amount of time the Spewer is "on", and hence doing damaged if so set up.

DormanDurationMax/Min: The amount of time the Spewer is completely off. Keep these numbers the same if you don't want randomness.

bAutoStart: If set to FALSE, then the name of the Spewer must be triggered for it to turn on and begin doing its thing.

ExpandDuration/ShrinkDuration: How long it takes the Spewer to build up into its full, damaging flame, and how long it takes it to shrink down to "off". Again, actors receive no damage during these phases.

MotionPitch/MotionYaw: Never messed with these, but I think you can get some bad-ass looking effects with them.

SpewerDamage: The amount of damage delivered when the Spewer is fully on and in its "Active" state. This damage amount is delivered 4 times a second, so you'll want to go easy on it.


SpewerForceMax/Min: This defines with how much force the particles are 'shot out'. Use it in conjuction with ParticleSystem->ParticleCount and ->LifeSpanMax/Min to get yourself a good-looking flame with a minimum number of particles.

SpewerLength/SpewerRadius: These are the important ones for making the Spewer cause damage. If they are set to zero, no damage will be done. Getting good values for these that match the apperance of the flame can entail some trial-and-error, but the best way to imagine the Spewer's damage zone is as a cylinder extending out from the Spewer's origin toward wherever the Spewer's directional arrow is pointed. SpewerLength defines how far out the damage cylinder goes, while SpewerRadius defines how 'fat' or 'skinny' that damage cylinder is.

PolyObject/Mover

PolyObjects are a new type of actor that are functionally similar to Unreal's Movers but have many unique properties. The player can break them, and you can have a bunch animating in the player's view with better performance than you'd get with Movers. The fundamental difference is that PolyObjects are Actors, and Movers are calculated with geometry. Therefore PolyObjects don't occlude. So if you look at a PolyObject door that is closed, the engine is still calculating geometry behind that door - so Movers are best for non-breakable doors.

InitialState: There are some new intialStates, but the most important of them is Destructible. This is not mutually exclusive; you can set up a PolyObject which has key frames and is TriggerToggleable/etc., but can still have it be breakable by setting PolyObjectDestroyable->bDestructible to TRUE.

PolyObjects, and now Movers also, can have 16 key frames instead of the original 8. This was infinite for a while, but implementing that in the Property interface could have been quite unwieldy, so 16 it is. More important, though, is that at each key frame a separate InterpolateEvent can be called. For daisy-chaining realistic crashes and such, this is invaluable, as it gives you a ton of Event slots to work with; if the third key frame of a falling boulder is located right where the boulder, in mid-flight, is to "hit" a wood beam and set that flying, you just call the wood beam Polyobject/Mover at that boulder key frame, and you've got yourself a nice realistic-looking interaction of the two.

Destructible PolyObjects: Under DamageThreshold you can set the amount of damage that the PolyObject can withstand before blowing up. The other settings for this are under the category PolyObjectDestroyable:

Debris will spawn out from the PolyObject's vertex position when it blows up, and can be tweaked with these settings:

DebrisSpawnRadius: dictates the overall size of the debris how far from its origin. Larger PolyObjects by default will create larger debris than smaller PolyObjects, as well.

DebrisTexture: you can highlight a texture and insert its name here, and the debris will have that texture. Good for visual consistency.

DebrisType: Under Classes->Effects->Debris you'll find different types of debris that behave according to what their 'material is'.

Matter: You can choose between pre-definite matter types that also affect how the debris behaves.

NumDebrisChunks: self-explanatory.

Under Sounds, you'll find a DestroySound slot. You can insert a suitable sound here that will play when the PolyObject is destroyed.

To make a PolyObject, you do as you would with a mover. Make sure that you "Transform Permanently" the active brush before adding it as a PolyObject, or you'll get some very apparent nasty side effects. Also, changing the location of a PolyObject's vertex position after it has been made will sometimes alter your texture alignment on the PolyObject, so you need to be careful there.

There are two ways to add a PolyObject, both of which require clicking on the new PolyObject icon located on the left side of the screen under the old Mover icon. It looks like three little stacked boxes cruising along.

If you just press that button alone, you'll get a "PolyObject". It has no default sounds and does not have a "DestroySound" slot.

Under Classes->Brush->PolyObject, you'll find "RunePolyObject". If you highlight this first in the Classes list and then click on the PolyObject button to add it to the world, you'll get a "RunePolyObject". It's identical to a "PolyObject", except that it has default sounds for things like doors and has a sound slot for when the PolyObject is destroyed. If you want to override those default sounds, you'll need to place the "Silence01" sound in those slots; it's a special sound located in the OtherSounds.uax package that is silent.

Finally, you can make an AttachPolyObject by highlighting "AttachPolyObj" in the Classes menu before clicking on the "add PolyObject" icon.

Pathing


I do not know how creature pathing was done in Unreal, but here's how to do it in RuneEd. Under Navigation in the Classes menu you'll find the PathNode actor. Lay these down as efficiently as possible to define routes that creatures can use to navigate your geometry. The best way to do this is by right clicking on your floor surfaces and selecting "Add Pathnode Here". Once added, it's important not to muck with the PathNode's z-coordinate. Pulling it up higher off the floor or lowering it can jack your pathing; on a flat surface, however, an added Pathnode can be moved around on the x- and y- axes without causing any trouble.

After you've laid down Pathnodes, RuneEd needs to compile the path network. To do this, select "Paths Define" in the Rebuild Menu (F8) under the "Lights" subheading. Note that RuneEd will draw path lines between PathNodes, ScriptPoints, and Inventory items (like a sword or shield). Paths will not be drawn to ScriptActions. If you make changes to your path network and hit "Play Level" without hitting "Paths Define", you'll likely get a crash, so be sure to redefine your paths whenever you make adjustments to these sorts of pathing actors.

In any of the four Editor views, you can turn on "Show Paths" under the "View" sub-heading. This will show you the actual path lines as well as give feedback on potential problems with your pathing. When a clean blue line is drawn between two PathNodes (or ScriptPoint, etc.), it means that that link is good to go. If, after defining Paths, you see gray lines between some of your pathnodes, it means creatures could have potential problems navigating those paths.

With troublesome, "non-blue" path links, there is additional visual information to help you narrow down what's wrong. A line drawn perpendicularly across a path line means that the geometry in that section is not wide enough, whereas a vertical perpendicular line means the geometry is probably not high enough. These perpendicular warning lines are based on our largest creature, the SnowBeast. That being the case, there will be times when you want to make a small tunnel for a Goblin, for instance.

After putting PathNodes inside this tunnel and hitting "Paths Define", you may get some gray lines and perpendicular warning lines - however, despite the warning it could work just fine for a Goblin... definitely not for a Snowbeast, of course, but you'll just have to play the level and find out via trial-and-error. Generally, Vikings and Goblins path quite generously, while for Snowbeasts you need to give them plenty of room in the world geometry.

There might be an occasion where you just can't get an enemy to path along a certain bit of geometry, no matter what you do (maybe the ledge where you want a creature to path is too thin and it's too late to change that geometry). In these rare cases you can try using an AutoLink, located also under the Navigation Class where PathNodes and ScriptPoints are located. You place the AutoLink as you would a normal PathNode, but you can daisy-chain two or more AutoLinks by giving them distinct tags and linking them to each other via the AutoLink->LinkTag property within the AutoLink itself.

Now if a creature paths to the first AutoLink, he should be forced to go to the next AutoLink, even if via normal pathing he would otherwise not 'prefer' to. These AutoLinks integrate into the normal pathing network. As a general rule, it's better to build so that you never need to use these AutoLinks, but they can save you in a pinch.

Scripting

This is no small topic, and to the uninitiated, could use a tutorial or two. For now, I'll stick with this document's format and write up reference material for the different actors involved and their important properties.

The basic way it all works is via ScriptPoints and ScriptActions. ScriptPoints, which build into the Path network (see "Pathing" above), are the basic building block. When a creature is ordered to go to a specific ScriptPoint, he will:

1.Physically move to the ScriptPoint
2.Perform whatever animating/scripting is contained in the ScriptPoint's properties
3.Be released as a free-roaming Pawn or be order by that ScriptPoint to carry on to another ScriptPoint or ScriptAction. ScriptPoints are not one-shot deals. Creatures can be ordered to the same ScriptPoint multiple times and different creatures/creature classes can be ordered to the same ScriptPoint.

If a creature is too far from a ScriptPoint when he is ordered to it (e.g. maybe it's two rooms away with tunnels in between) he may not be able to get to it, even if a clean network of Pathing lines should lead him to it fine. When trying to script creatures to cover larger differences, it's best to daisy-chain ScriptPoints linked to each other to form the path. Here are the essential properties in a ScriptPoint:

ScriptAnim->ArriveAnim/ArrivePause: Here you can insert the name of an animation you would like a creature to play once it has arrived at the ScriptPoint. Whatever the ArrivePause is set to is how long the creature will loop that animation before proceeding to the next action. If ArrivePause is set to zero, the animation will loop once. As far as knowing what the animation names are, I don't know our current plan for releasing all that information. For starters you could look at ScriptActions and ScriptPoints within the included single-player maps to get some names...but that's not the most elegant solution. More on this in the future...

ScriptSync->LookTarget: The Pawn's head will be locked on to whatever target Tag you give here, and will be until it is later given a new look target. To have them look at Ragnar, type in "Player". LookTargets can be just about any other actor, as well.

ArriveEvent: This event will be fired when the creature arrives at the ScriptPoint.

bReleaseUponArrival: If set to TRUE, the creature will be released into its default free-roaming state once it has completed its ArriveAnim/ArrivePause/etc. There is an extra bit of control in here that is important to note. Let's say you set bReleaseUponArrival->FALSE, and the pawn is given a NextOrder of Scripting (see below) to some ScriptPoint across the room. After completing its actions at the current ScriptPoint, then, the creature will start trotting over to that next OrderTag location. However, the creature will do this like a robot -i.e. he will ignore the player and everything else. The player could whack on this creature as it's in transit and the creature would trudge along. This is invaluable when you want to make damn sure a creature follows a certain order of Scripting and can't be interfered with.

But on the other hand, if you set bReleaseUponArrival->TRUE and you are still giving the Pawn further scripting orders (i.e. telling it to head next to a ScriptPoint across the room, again), you'll have a smarter-interacting creature. What will happen is that the creature will still go and head over to that next ScriptPoint, but along the way as he heads over there he can be 'interrupted'. If he sees Ragnar or is otherwise alerted, he will break from scripting and come attack the player.


TurntoRotation: If set to TRUE, the creature will, upon arrival, rotate to align itself with the directional arrow of the ScriptPoint. Usually best left at FALSE.

bWalkToThisPoint: Self-explanatory.

NextOrder: if you would like the creature to head to another ScriptPoint next (or carry out a ScriptAction/ScriptDispatcher next), type "Scripting" into this slot.

NextOrderTag: This is where you type in the name of the next ScriptPoint you would like the Pawn to head to or the next ScriptAction/ScriptDispatcher you would like it to carry out.

ScriptActions are an invaluable addition to our scripting tools. In many ways they are like ScriptPoints, but the primary difference is that when a Pawn is ordered to a ScriptAction, he does not physically first walk over to wherever the ScriptAction is located, and he never will. The only way to get order a creature along specific map navigation is via ScriptPoints. ScriptActions are used for more complicated scripting than ScriptPoints allow for. Quite often in our maps you'll see a creature Ordered to head over to a ScriptPoint (and thus getting him into the desired position), at which point he is immediately next ordered to a ScriptAction. Since there is no physical walking involved, a creature will always carry out a ScriptAction immediately upon being ordered to do so. [However, you can affect a creature's rotation via ScriptActions just as you can with ScriptPoints.] Following are the significant settings for ScriptActions:

ScriptAnim: The same as for ScriptPoints

ScriptSound: The same as for ScriptPoints, except that with ScriptActions you can insert an independent sound playback delay.

LookTarget: Same as for ScriptPoints.


ControlHead/ControlMouth/ControlTorso/TimeGranularity: These give you the ability to 'animate' a Pawn a good deal at a ScriptPoint. You control these by typing in strings of letters into the blank text space. With ControlHead, the letter 'a' denotes that the head is turned all the way left, while the letter 'z' denotes that the head is turned all the way right. So if you wanted a creature to look left-right-left-right, you'd type in the text string "azaz". ControlTimeGranularity defines how much time each letter represents. If you set ControlTimeGranularity to '1' (one second), the left-right-left-right sequence will take a total of 4 seconds. 'a' is left and 'z' is right for ControlTorso, as well. For ControlMouth, 'a' means the mouth is fully closed and 'z' means it's open wide like a nutcracker. For more natural mouth movements I wouldn't go too far past the letter 'p'.

bFireEventImmediately: Under the Events property of a ScriptAction (just above "Tag"), you can type in the name of an Event you would like fired off as part of the ScriptAction. If bFireEventImmediately is set to TRUE, that Event will be fired the instant a Pawn is Ordered to the ScriptAction. If it is set to FALSE, that Event will not fire until the Pawn has finished all the animation/syncing defined in the ScriptAction.

bReleaseUponCompletion/bTurnToRotation: The same as with ScriptPoints (see above).

bWaitToBeTriggered: Now this one is a real save-all. If this is set to TRUE, the Pawn Ordered to this ScriptAction will 'hold' indefinitely. Once an Event has called the Tag of this ScriptAction, the creature will carry it out. If set to FALSE, the creature will carry out the ScriptAction immediately upon being Ordered to do so. Here's an example of a perfect use:

Let's say you want a creature in the distance to run over to a holding point, but not free up and attack the player until the player nears that holding point. What you do is put a ScriptPoint at that holding point, and Order the creature to that ScriptPoint. Make that ScriptPoint's NextOrderTag be a ScriptAction; within that ScriptAction, set bReleaseUponArrival->TRUE and bWaitToBeTriggered->TRUE. Then put a player proximity Trigger over by where you want the player's proximity to release the creature; make the Event of that Trigger be the name of the ScriptAction. When you play the level, the creature will run over to that ScriptPoint. When the player sets off the proximity Trigger, the ScriptAction will be called and will then carry out... because it had been set to bReleaseUponArrival->TRUE, the creature will then release at that point and come running at the player.


NextOrder/NextOrderTag: Same as with ScriptPoints (see above).

So how do you Order creatures to these ScriptPoints/ScriptActions/ScriptDispatchers in the first place? You can do it with an OrdersTrigger (it's a regular Trigger with a special property for typing in a creature name Tag and a ScriptPoint/etc. name Tag.) You can do it with a SpecialEventRune whose initial state is set to OrderObject [see the "Trigger" section above], and SpecialEventRune can in turn be called by a regular Trigger, a Dispatcher, an Event fired off a ScriptAction, a creature's death Event [Pawns' "Event"s are fired when they die], damn near anything. Or, you can place creatures in the map with Orders built-in or ActorGenerate [see "KeyPoint" above] a creature with built-in Orders. These built-in Orders are described here:

SpawnOrders/SpawnOrdersTag: The creature will carry out these orders the second he is actorgenerated in or the map begins. Type in "Scripting" for SpawnOrders and the name of a ScriptPoint/Action/Dispatcher for the SpawnOrdersTag.

SpawnAlertOrders: The creature will carry out these orders as soon as he sees the player or is otherwise alerted to the player's presence. Type "Scripting" for SpawnAlertOrders

SpawnTriggerOrders: When the specific Tag name of the creature is called by an Event, the creature will carry out these orders.

With SpawnTriggerOrders/SpawnAlertOrders/SpawnOrders, you simply leave those slots blank to disable them; this is the default.

You'll notice that you'll almost exclusively be typing in "Scripting" for the Orders themselves, and then the Tag of a ScriptPoint/Action/Dispatcher for the actual OrdersTag. There are some other orders other than "Scripting" that you can try. Actually, I don't know if the bulk are supported any more (I'd avoid the "Attack" order), but one that you can use is "Roaming". If a creature is given Orders of "Roaming" (with no subsequent OrdersTag), that creature will randomly roam around the geometry until he sees the player is alerted. The DarkVikings at the end of Thor1.run are all "Roaming", so they're not always in the same position whenever you play.


Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: