Sega 500 Mutators Jeff “Ezeikeil” Giles

Slides:



Advertisements
Similar presentations
Review of Exercises from Chapter 17 Statistics, Spring
Advertisements

1 Data Structures Data Structures Topic #2. 2 Today’s Agenda Data Abstraction –Given what we talked about last time, we need to step through an example.
CS 31 Discussion, Week 6 Faisal Alquaddoomi, Office Hours: BH 2432, W 4:30-6:30pm, F 12:30-1:30pm.
Lecture 22 Miscellaneous Topics 4 + Memory Allocation.
Conditional & Joint Probability A brief digression back to joint probability: i.e. both events O and H occur Again, we can express joint probability in.
CS 304 Project Kirk Scott 1. The specifications for this project will be subject to possible minor revision as the semester progresses depending on what.
CS 11 C track: lecture 5 Last week: pointers This week: Pointer arithmetic Arrays and pointers Dynamic memory allocation The stack and the heap.
Sega 500 Intro to Bot AI Jeff “Ezeikeil” Giles
Nachos Phase 1 Code -Hints and Comments
Data Structures Week 5 Further Data Structures The story so far  We understand the notion of an abstract data type.  Saw some fundamental operations.
Bill's Amazing Content Rotator jQuery Content Rotator.
Sega 500 Close Combat weapons Jeff “Ezeikeil” Giles
Module 10: Simple Inheritance #1 2000/01Scientific Computing in OOCourse code 3C59 Module 10: Simple Inheritance In this module we will cover Inheritance.
Data Structures and Algorithm Analysis Hashing Lecturer: Jing Liu Homepage:
JMD2144 – Lesson 4 Web Design & New Media.
4.1 Instance Variables, Constructors, and Methods.
Polymorphism, Inheritance Pt. 1 COMP 401, Fall 2014 Lecture 7 9/9/2014.
Sega 500 More replication Jeff “Ezeikeil” Giles
Art 315 Lecture 5 Dr. J. Parker AB 606. Last time … We wrote our first program. We used a tool called GameMaker. The program we wrote causes a ball to.
Microsoft ® Office Outlook ® 2003 Training See and share multiple calendars CGI presents:
Sega 500 Placing target boxes on the HUD Jeff “Ezeikeil” Giles
Question of the Day  On a game show you’re given the choice of three doors: Behind one door is a car; behind the others, goats. After you pick a door,
CIT 590 Intro to Programming First lecture on Java.
Addressing Concerns from Patients General rule of thumb: If a person does not want to answer these questions, move on. Do not force the issue. Simply record.
Collecting Things Together - Lists 1. We’ve seen that Python can store things in memory and retrieve, using names. Sometime we want to store a bunch of.
Agenda Review C++ Library Functions Review User Input Making your own functions Exam #1 Next Week Reading: Chapter 3.
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 3 More About Classes Jeffrey S. Childs Clarion University of PA © 2008, Prentice Hall.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Simple Classes. ADTs A specification for a real world data item –defines types and valid ranges –defines valid operations on the data. Specification is.
Copyright Curt Hill Variables What are they? Why do we need them?
1 CS161 Introduction to Computer Science Topic #9.
Sega 500 GUI & Menus Jeff “Ezeikeil” Giles
Sega 500 Creating a New Game Jeff “Ezeikeil” Giles
Fall 2002CS 150: Intro. to Computing1 Streams and File I/O (That is, Input/Output) OR How you read data from files and write data to files.
Gold – Crystal Reports Introductory Course Cortex User Group Meeting New Orleans – 2011.
EGR 2261 Unit 11 Classes and Data Abstraction  Read Malik, Chapter 10.  Homework #11 and Lab #11 due next week.  Quiz next week.
Interfaces About Interfaces Interfaces and abstract classes provide more structured way to separate interface from implementation
Lesson 2: Reading a program. Remember: from yesterday We learned about… Precise language is needed to program Actors and Classes Methods – step by step.
Adding and Subtracting Decimals © Math As A Second Language All Rights Reserved next #8 Taking the Fear out of Math 8.25 – 3.5.
Sega 500 Scripted events and Sequences Jeff “Ezeikeil” Giles
Sega 500 Combo Mutator Jeff “Ezeikeil” Giles
Word Create a basic TOC. Course contents Overview: table of contents basics Lesson 1: About tables of contents Lesson 2: Format your table of contents.
Programming Fundamentals. Topics to be covered Today Recursion Inline Functions Scope and Storage Class A simple class Constructor Destructor.
Program Organization Sequential Execution: One line done after the other Conditional Execution: If a test is true, one section is done, otherwise another.
Sega 500 Precaching in UT2003 Jeff “Ezeikeil” Giles
BIT 115: Introduction To Programming Professor: Dr. Baba Kofi Weusijana (say Doc-tor Way-oo-see-jah-nah, Doc-tor, or Bah-bah)
Changing HTML Attributes each() function Anonymous Functions $(this) keyword.
CS 31 Discussion, Week 5 Faisal Alquaddoomi, Office Hours: BH 2432, MW 4:30-6:30pm, F 12:00-1:00pm (today)
IS2803 Developing Multimedia Applications for Business (Part 2) Lecture 2: Introduction to IS2803 Rob Gleasure
Network Replication Possibly the ugliest thing to learn this semester Many different states Simulated Functions Is it an Event or function? Roles.
University Learning in Schools Computing Games Programming Lesson 5.
HTML Review * is used as a reference for most of the notes in this powerpoint.
J2EE JSP Custom Tag Libraries 1 3 JSP: Custom Tag Libraries.
Chad’s C++ Tutorial Demo Outline. 1. What is C++? C++ is an object-oriented programming (OOP) language that is viewed by many as the best language for.
Module 9: Operator overloading #1 2000/01Scientific Computing in OOCourse code 3C59 Module 9: Operator Overloading In this module we will cover Overloading.
Dynamic Presentation of Key Concepts Module 6 – Part 4 Special Cases and Approaches with First Order Circuits Filename: DPKC_Mod06_Part04.ppt.
Advance startup options Shift Restart. Restart options.
Lecture 8: Collections, Comparisons and Conversions. Svetla Boytcheva AUBG, Spring COS 240 Object-Oriented Languages.
Sega 500 More on Possession and Using Stuff Jeff “Ezeikeil” Giles
Programs – Preprocessing, Compilation and Linking
Introduction to Python
EGR 2261 Unit 4 Control Structures I: Selection
Explain what touch develop is to your students:
Unreal Engine and C++ We’re finally at a point where we can start working in C++ with Unreal Engine To get everything set up for this properly, we’re going.
OOP Paradigms There are four main aspects of Object-Orientated Programming Inheritance Polymorphism Abstraction Encapsulation We’ve seen Encapsulation.
What Are They? Who Needs ‘em? An Example: Scoring in Tennis
ARRAYS 1 GCSE COMPUTER SCIENCE.
Variables Title slide variables.
Presentation transcript:

Sega 500 Mutators Jeff “Ezeikeil” Giles

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.

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.

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.

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.

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.

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

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

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!!!”

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.

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

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.

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 also a linked list. Look at the declaration: class Mutator extends Info DependsOn(GameInfo) native; var Mutator NextMutator;

But first… What is this DependsOn operation?

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,

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;

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.

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;

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.

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.

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.

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.

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.

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.

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

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.

About the base class function class 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.

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.

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

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

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.

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

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

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 “ }

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.")

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

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.

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); }

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…

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

Building a mutator Look what happens when I jump. I nearly go into orbit! What the heck is going on?

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…

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

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.

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

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

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.

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.

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.

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

A bit of polish. *46656 !?!? My god! No wonder we go into orbit!

The solution: We’ll, not that we know why we were launching our pawns, How do we fix it.

The solution: First off, now that we’ve realized that we don’t want to loop over all the controllers here. It’s apparent that the modify player does it for us, we just need to set the new value.

The solution: Yup one function. function ModifyPlayer(Pawn Other) { Other.jumpz = Other.default.jumpz*2; super.ModifyPlayer(other); }

The Lesson? In many places in the code, objects can be link together in this manner, and it’s frequently not documented all that clearly.

The Lesson? Also, UT doesn’t really have any build in data structures (like linked lists and hash tables) to conveniently store stuff. Hence we often have to make our own. And a linked list in this fashion is the most common.

Tomorrow We’re going to expand on this to create a mutator that had the jump doubler as part of an adrenalin combo where, when the combo is active, the player can jump twice as high…along with combo effects.