1 / 57

Sega 500

Sega 500. Mutators. Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles. So far. We’ve created changes to the UT game play by modifying & creating our own content. HUD Weapons Game play / timing However all our changes have been restricted to game types.

freira
Download Presentation

Sega 500

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sega 500 Mutators Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles

  2. So far • We’ve created changes to the UT game play by modifying & creating our own content. • HUD • Weapons • Game play / timing • However all our changes have been restricted to game types.

  3. Today • We’re going to look at an alternate method of changing how UT runs / plays, known as mutators. • The goal of the week is to cover how to build a mutator & wrap it up into an installer package for distribution.

  4. Mutators…What are they? • Mutators are special classes which modify the game being played in some way. Normally, mutators are single minded in their goals, such as just making the players fat, or reducing the gravity. • As they’re name suggests, they are pretty good at modifying and replacing stuff. Although this can be accomplished by creating new game types, one of the main advantages of the Mutators is that you don't need a new game type.

  5. Mutators…What are they? • In fact, you can combine Mutators with any game type, including 3rd party mods. • Provided they are properly written, they can be linked together, thus allowing you to more fully customize your gaming experience. • For instance, it allows you to be fat AND have low gravity.

  6. Mutators…What are they? • Another reason to use Mutators is that during network play, the clients will not need to download anything to join, unless of course, they don’t have that mutator or it makes use of actors not shipped with Unreal.

  7. Mutators…What are they? • So running one for an example… • Big head, instagib.

  8. Mutators…What are they? • In game we get Changing head sizes… As you can see, Mandible here is not doing all that well And Instagibbers for all

  9. Mutators…What are they? • After a bit of kick’n ass & take’n names… • “Look a-his grrreat- huuge- crainium! It’s got It’s own weathar sistem!!!”

  10. Mutators…What are they? • This is really cool functionality to have at our fingertips. Radically changing the game WITH OUT changing the game type. • In effect, Mutators are basically replacement classes. They are launched whenever an actor is spawned and by overriding some of the classes found in the standard Mutator class, we can control what items are to be spawned and which ones to scrap.

  11. Mutators…What are they? • You’ll find the mutator base class here: Object Actor Info Mutator

  12. Mutators…What are they? • With the following header: • Mutators allow modifications to gameplay while keeping the game rules intact. • Mutators are given the opportunity to modify player login parameters with ModifyLogin(), • To modify player pawn properties with ModifyPlayer() • To change the default weapon for players with GetDefaultWeapon() • To modify, remove, or replace all other actors when they are spawned with CheckRelevance(), which is called from the PreBeginPlay() function of all actors except those (Decals, Effects and Projectiles for performance reasons) which have bGameRelevant==true.

  13. About the base class • The first thing to note about it is that the mutator class not only has functionality to change the game dynamics, but is alsoa linked list. • Look at the declaration: • class Mutator extends Info • DependsOn(GameInfo) • native; • var Mutator NextMutator;

  14. But first… • What is this DependsOn operation?

  15. What the Wiki says… • DependsOn • Takes a class name as parameter. It allows you to automatically import the structs, constants, and enums of a class. You don't need to specify a package name. You can then refer to the structs, enums, and constants using the syntax ClassName.TypeName. The dependsOn modifier takes exactly one parameter. If your class depends on more classes you have to use the modifier several times,

  16. Well, hang on a sec • We’re in the mutator class, so why are we declaring a mutator first thing? • class Mutator extends Info • DependsOn(GameInfo) • native; • var Mutator NextMutator;

  17. About the base class • Doing so allows the mutators to be chained together and iterated over. • This is very important to remember otherwise, you may not be able to compound you mutators together.

  18. About the base class • For example, from the mutator’s destroyed function: function Destroyed() { local Mutator M; // remove from mutator list if ( Level.Game.BaseMutator == self ) Level.Game.BaseMutator = NextMutator; else { for ( M=Level.Game.BaseMutator; M!=None; M=M.NextMutator ) if ( M.NextMutator == self ) { M.NextMutator = NextMutator;

  19. Base class Defaults • Default properties: • IconMaterialName: allows mutators to have a symbol/graphic associated with them in the form TexturePack.Texture. • ConfigMenuClassName: This is used if the mutator needs an extra config menu for special settings.

  20. Base class Defaults • GroupName: • If there are two mutators in the same group, only one is allowed to be used at a time, e.g. Arena and No Superweapons. • FriendlyName: This is the name seen in the mutator screen when starting a game.

  21. Base class Defaults • Description: A longer description/help text to tell players what the mutator does. Note: the real description is stored in the int file and over rides the one listed here.

  22. About the base class • This class also comes with a core set of basic functions • And, unlike some of the other Script, has some useful comments. 

  23. About the base class • event PreBeginPlay() and function bool MutatorIsAllowed() • if the mutator isn't allowed, get rid of it. Mutators are allowed if this isn't the demo, or if the class is a basic Mutator. • function Destroyed() • The Destroyed() function for mutators must perform the added task of removing it from the linked list.

  24. About the base class • function ModifyLogin(out string Portal, out string Options) • ModifyLogin could be used to create some special effect when a player logs in, or make an announcement • function ModifyPlayer(Pawn Other) • called by GameInfo.RestartPlayer() change the players jumpz, etc. here • ModifyPlayer is commonly used to change speed, gravity, jump height, health and such.

  25. About the base class • function Class<Weapon> GetDefaultWeapon() • return what should replace the default weapon mutators further down the list override earlier mutators. • function Class<Inventory> GetInventoryClass(string InventoryClassName) • return an inventory class - either the class specified by InventoryClassName, or • a replacement. Called when spawning initial inventory for player.

  26. About the base class • function string GetInventoryClassOverride(string InventoryClassName) • return the string passed in, or a replacement class name string. • function string GetInventoryClassOverride(string InventoryClassName) • return the string passed in, or a replacement class name string.

  27. About the base class • function class<Weapon> MyDefaultWeapon() • return the default weapon used by the mutator. • function AddMutator(Mutator M) • adds a mutator onto the end of the linked list. • function string RecommendCombo(string ComboName) • used to modify the Combo Adrenalin moves used by players.

  28. About the base class • function bool ReplaceWith(actor Other, string aClassName) • Call this function to replace an actor Other with an actor of aClass. • scans the whole map replacing Other with aClass. It is better to call this than to modify it. • function bool AlwaysKeep(Actor Other) • Force game to always keep this actor, even if other mutators want to get rid of it • Important because mutators are supposed to be pretty compatible with each other.

  29. About the base class • function bool IsRelevant(Actor Other, out byte bSuperRelevant) • function bool CheckRelevance(Actor Other) • function bool CheckReplacement(Actor Other, out byte bSuperRelevant) • These functions check whether an actor is required by the game or not. It is required if a mutator has called AlwaysKeep() on it. CheckReplacement is used, for example, by NoSuperWeapons mutator to replace the Ion Painter with the Sniper Rifle

  30. About the base class • function PlayerChangedClass(Controller aPlayer) • Called when a player sucessfully changes to a new class

  31. About the base class • function GetServerDetails( out GameInfo.ServerResponseLine ServerState ) • function GetServerPlayers( out GameInfo.ServerResponseLine ServerState ) • Server stuff. GetServerDetails returns the usual details of the server, plus something telling everyone that our mutator is active on it. GetServerPlayer does nothing (obviously) and ParseChatPercVar could be used for silencing players etc.

  32. About the base class • And that concludes a very high level walk through of the mutator base class. • Now lets do something with it…

  33. Building a mutator • As always, starting simple. • I’m going to implement a real basic mutator that simply doubles the players jump height.

  34. Building a mutator • Getting the set up stuff out of the way first, we derive our class off the mutator base class and set up our defaults. • DefaultProperties • { • IconMaterialName="MutatorArt.nosym" • ConfigMenuClassName="" • GroupName="SuperBounce" • FriendlyName="Super Bounce" • Description="Doubles jump height “ • }

  35. Building a mutator • And now add to the int file: • So that we can call it from the menu. • [Public] • Object=(Class=Class,MetaClass=Engine.Mutator,Name=Eze.Bounce , Description="Doubles jump height.")

  36. Building a mutator Our mutator But right now, it doesn’t do a thing.

  37. Building a mutator • Right, now we want to modify the players jump height…but how…err… • Oh yeah, we have a function for that…Modify player…Sounds logical.

  38. Building a mutator • Our function: • function ModifyPlayer(Pawn Other) • { • local Controller C; • for (C = Level.ControllerList; C != None; C = C.NextController) • { • if (C.Pawn != none ) • { • C.Pawn.jumpz *=2; • } • } • super.ModifyPlayer(other); • }

  39. Building a mutator • Remember the Level has a list of all the controllers in existence in the game, so well just iterate over all of these with the for loop. • And then double the jumpz value with C.Pawn.jumpz*=2; • Build & give it a shot…

  40. Building a mutator • Looks like it runs fine… But what’s that stuff falling from the sky? Hrmm…Weird.

  41. Building a mutator • Look what happens when I jump. <KA-PWING!!!> • I nearly go into orbit! What the heck is going on?

  42. Building a mutator • Here’s the mistake I made, I placed the following log in the for loop in my home build Log(c.PlayerReplicationInfo.PlayerName$"------------"$C.Pawn.jumpz); • …look at what it spat out…

  43. Building a mutator • Some insanely huge float values…in the tens of thousands! • Heh? The jumpZ default is only defined as JumpZ=+00420.000000 in the pawn class. • Look again at the log…

  44. Building a mutator • The player names repeat and get doubled with every pass…even before the match starts. • So what’s going on? The mutator is getting called with every access to any pawn. Doubling all of the jumpZ’s. • Causing an exponential increase in our jump height.

  45. Building a mutator • The solution, after much head scratching, was surprisingly simple. I was just how I was accessing my values. • It’s a one line fix. C.Pawn.jumpz = C.Pawn.default.jumpz*2; • Double my default jump height and then assign it to my pawns jump height. This will allow for dynamic changes specific to the pawn type 

  46. Congrat’s • You’ve just completed you first mutator, ready for release to the world.

  47. A bit of polish. • On a second look at this modify player function, I had a bit of an epiphany. • Or some might say that I grew a brain.

  48. A bit of polish. • Looking back at what a mutator fundamentally is….a node in a linked list, it occurred to me that using the loop in the modify player function is a bad idea… …real bad.

  49. A bit of polish. • Think about this for a moment, I’ve a list of objects that I’m using to modify my players in turn…in effect, each node has a turn at processing a player. • Thus, each pawn that gets processed in ModifyPlayer, modifies all other players in the game.

  50. A bit of polish. • Gah! That’s bad! • But just for a chuckle, lets say there are 6 players in the game, using the controller loop: (C.Pawn.default.jumpz*2) * 6 * 6 * 6 * 6 * 6 * 6 (C.Pawn.default.jumpz*2;)*6^6 (C.Pawn.default.jumpz*2;)*46656

More Related