As a supplement to the Psionics Mutator version 1.0 source code release, this information tutorial will help guide people through the use and modification of it. It’s very brief and hastily put together but anyone with an understanding of UT should understand it pretty quickly. If you are completely new, I suggest googling for some basic tutorials before attempting modifications on this.
Hopefully soon I'll get an actual tutorial on creating a move up, check back later, feel free to add/modify this where things don't make sense...
This class is added to any AI bot that joins a match; it extends the replication info that is used by an ordinary human player in order to add thought process capabilities. The thinking cycle occurs every one second and works by cycling through all the available moves and the moves weighting function to determine usefulness. Therefore this class does very little independent thinking and relies on the functionality of the moves themselves. This allowed for a much more extensible architecture.
A simple damage type for the blast ability.
This is a panel for the main mutator configuration window that shows both the history (not really relevant to gameplay) and a description of what the moves can do. It shows off how to do list box selection changes and linking together strings to create a scrolling text box.
The meat and potatoes of the mod. This is the main mutator class, which extends from the personally developed xMutator, to make some stuff easier, such as adding Replication Info’s, interactions and HudOverlays. It sets up the global mutator config window as well as the client side (xMutator function) one. The xMutator is explained in more detail in Appendix A.
This panel is where the global options are set in the mutator config window. Allows the user to change things such as the moves allowed, leeching options, power options and game speed option. This class is representative of your average form.
This class pretty much takes the code from the Mutant Game Type and modifies that emitter to create the effect you see when powering up (red glowy bits.) This emitter works in multiplayer (can be seen by other users.)
Simply adds an adrenaline combo to the mutator for extra functionality. A simple combo that converts adrenaline into psionic energy (using up-up-up-down.) An example of creating combos.
Serves as a base for both the DescriptionTabPanel and the OptionsTabPanel by creating a tabbed menu system. As such this is an example of how to use the tab control for menus.
This is an example of how to create custom HUD elements to a mutator. Shows off how to use the render function and import textures using pre-processor terms. The HUD draws the element that appears at the top right of screen, directly under the adrenaline icon.
This is the menu that appears when accessed from the client-side mutator config menu (an xMutator function.) it allows the user to set whichever moves they want access to as well as giving them access to the move config menu. This is an example of how to change things client side.
This class deals with the key presses of starting a move and changing a move. It also has links to the hud element in order to change it (as most mutators will undoubtedly need.) Also deals with the powering up of a character. As a lesson in history, this class originally contained all the code for dealing with the moves (now part of PsychicLinkedReplicationInfo.) The reason this stuff was moved was replication issues, so note that do not put any replication stuff here as Interactions ARE NOT replicated.
Binds the keys for use by the mutator (oh no way, really!) An example of how to create custom key bindings.
This is one of the most important classes as it gives the player access to their moves. A LinkedReplicationInfo is both a client and server object that can be added to the PlayerReplicationInfo object. This class contains information on which moves there are, what is selected, what is being used and the energy available. It also deals with level changes and the powering up effect. This is a very good class to look at when trying to get replication working in your mod, as it does do a lot of replication stuff. Note that an LRI must be added ON THE FIRST TICK of a controller object, and must be added SERVER SIDE, otherwise it won’t add for some stupid reason. Use the xMutator AddServerSide() function to get around this in your mutators.
This is the abstract base class of ALL moves in the mutator (sorta like the weapon class in UT2004.) Any new moves should extend from this class. This class contains the functionality to start and stop moves as well as set their costs, both for initialisation and duration. AI code can also be placed here (botStartMove, getBotWeight, getBestlevel and botUsing) so that the AI can use the move, note you must also set botuseful to true. A custom menu can also be attached for custom move attributes (or they can be added using a mutator-like playinfo thing.)
These are the moves, they are fairly easy to understand and self explanatory (and I am lazy!)
Works the same way as the Mutator config menu does in that it aggregates all the moves available and gives you options to change how the function (see PsychicMovePerception for an example.) This is an example of aggregating using Info’s.
This is added onto the end of the game rules list by the mutator. It allows for the moves to plug directly into some of the functionality of it (although at present it only taps what I needed, there is scope for moves to access other functions.) Also deals with leeching. An example of a mutator adding custom game rules.
Used by the PsychicMove sight as a camera.
The mutator itself is the class that gets everything up and running. With it we set all the variables up as well as any other players (both bot and human) with the extra functionality they require. This particular mutator uses the xMutator (Appendix A,) which allows for some easy ways to do complex tasks as well as making for reduced key binding needs. This mutator pretty much pushes the mutator to the limits, chances are if you need to do something with a mutator you can find out how here. Does things such as:
- Adds a LinkedPlayerReplicationInfo ( Server side)
- Adds an Interaction ( Client Side)
- Adds a HudOverlay ( Client Side)
- Modifies Pawns
With a mutator, please remember to do things such as:
- Call Super. in functions to play nice with the rest of the mutators
- Set the name, description and group properly
In UT2004 the GUI can be very tricky to get working properly (thankfully fixed in UT3.) The GUI must first be coded by hand but can then be modified in-game by setting bModAuthor to true within the UT2004.ini file and then hitting Ctrl-Shift-D in game. Instructions for use appear on screen. This tool is invaluable in creating your menu’s visually. Just as a reference, the WinXXXX values are in percentages of the parent frame, so top-level objects are a percentage of the entire window, i.e. 0.5 = 50% of the window. The GUI in the mutator has a top-level menu that uses a tabbed interface, tabs need to be added with an associated panel, which is displayed when selected. These panels have to be created in their own class with the positioning elements set to be relevant to the size of the panel, i.e. 0.5 = 50% of the panel size (which is subsequently based on the window size.) Note that all components of a GUI must be Automated in order for them to work properly (or even show up.) Components are created in the default properties by using:
Begin Object Class=[GUIClassname] name=[Anything]
... [Default Values]
[Global Object Name] = [Anything]
The interaction is a client-side only object that allows the modder to deal with KeyPresses and the like. If you do not plan on having your mutator multiplayer compatible then LinkedRepInfo stuff can be merged here for convenience (although I don’t recommend it). Note that an interaction will stay with a player, EVEN IF THEY EXIT THE LEVEL. Make sure to call:
In NotifyLevelChange() or you will end up having multiples of the same interaction and many error messages in your log. The interaction is also a good place to have a link to your custom hud elements for easy reference than searching through your entire HUDOverlay list of your hud every time you need it.
Remember INTERACTIONS ARE ONLY CLIENT SIDE.
More advanced mutators require visuals to display information, this is where the HUD overlay comes in. The HUD Overlay can be added to a list in the master HUD and is then drawn as appropriate. The HUD Overlay does all it’s drawing in it’s Render(Canvas C) function using the canvas object. Note that a HUD Overlay cannot use master HUD things such as SpriteWidgets or TextWidgets. As a general rule, remember the basic hud elements already on the HUD in UT and position yours to fit along with these and not obscuring them.
Remember HUDS ARE ONLY CLIENT SIDE.
The Replication Info
This is the primary class that allows the mutator to work in multiplayer. A LinkedReplicationInfo is a class that allows for LRI’s to be chained together off the main PlayerReplicationInfo object that a player always has attached. These classes are both Client and Server side (they must be created on the server to work) and are the best place to store custom, player specific information. For example the Psionics Mutator stores information on what moves are available, what is selected and current stats for levels and energy. As a general rule, if you would include it in the pawn or controller if you were creating from scratch, include that variable here. To get access to your LRI, check out the functions I created to give easy access (GetPLRI()), essentially it scans through the list until it finds the one I need and then returns it. The PLRI also deals with the effect, which is why the effect appears on all other clients in multiplayer.
Remember LINKEDREPLICATIONINFOS ARE BOTH CLIENT AND SERVER SIDE
The Game Rules
A mutator can add custom rules to modify the game. These custom GameRules are added to a list in the Game object (Level.Game) and can be accessed as such (a very similar way to the way an LRI is accessed.) GameRules can modify damage and change the way kills are scored as well as a host of other functions. In the psionics mutator, this class is used to allow the moves access to things such as modifying damage (see PsychicMoveShield,) as well as allowing the leeching to work.
The Psychic Move Class
All psionic moves must extend from the class ‘PsychicMove,’ and
Must implement the following methods and variables:
- level[x]Move() where x = 1 to 5 - The move code
- endMove() - Clean up when finished
- levelInitailCost[1 - 5] - Energy cost to begin move
- Icon - The icon to display on the HUD
- bInstant - Used instantly or power drops over time
The following may be implemented if you wish:
- backfire() - Occurs when temperature is too high
- moveScoreKill() - Called by gamerules scoreKill
- moveNetDamage() - Called by gamerules netDamage
- moveRender() - Called by HUD render
- moveTick() - Called by Tick
- secondaryFunction() - A secondary function of move
Other Descriptive variables:
- thename - The name of the move
- description - A description of what the move does
- levelDescription - A description of what each level does
- levelUsingCost - Cost of using per second if bInstant=true
Variables used by PsychicMove (don’t modify):
- levelUsed - The level that the move last used
- user - A link to the controller who uses this move
- getPowerModifier() - Returns a value between 0.5 and 2 based on score/death ratio for use with handicapping
For bot support:
- botStartMove() - Bot starts using a move.
- getBotWeight() - Called by bots to determine which move is best to use at current time.
- getBestLevel() - Get the best level for the bot to use.
- botUsing() - Called whenever the bot is using a move to determine what to do.
- botuseful - Set to true if bots can use this move
- thename= "Default super class power"
- description="An abstract class"
- levelDescription[x]= "Levelx"
- RemoteRole= ROLE_SimulatedProxy
Appendix A – xMutator
The xMutator was developed by me to allow some functionality that the current mutator doesn’t have, currently only my Psionics and Radar mutators use it. The source is available with the Psionics Mutator v1.0 source download. Essentially the xMutator adds:
- ClientSideInitialization( PlayerController) – Initialises a player client side for interactions, huds, etc.
- ServerSIderInitialisation( Controller) – Initialises a player server side for LRI’s, etc.
- ServerInitialisation() – Called before above for the mutator
- AddAnInteraction( PlayerController, Class, Single) – Convenience for interaction adding
- AddAHudOverlay( PLayerController, Class, Single) – Convenience for hud adding
- AddCustomReplicationInfo( Controller, Class, Single) – Convenience for LRI adding
- GetAnXXXXX( PlayerController, Name) – Convenience for getting above values
- ClientMenuFillPlayInfo( PlayInfo) – Same as FillPlayInfo except for client menu
- ClientSettingChanged( PlayerController, PlayInfo) – Called when client config menu is exited for updating values
- GetValueFromPlayInfo( Property, Group, PlayInfo) – Gets a value for a particular key for mutator
- GetExternalValueFromPlayInfo( class, prop, group, PlayInfo) – Gets a value for a particular key for a particular class