Announcement

Collapse
No announcement yet.

DM Mutator - subtract point for death (modding tips requested)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DM Mutator - subtract point for death (modding tips requested)

    So this simple mutator (tested with DM, where's it's intended to be used) subtracts a point for every death.

    The basic idea is to make DM a more cautious affair, however in it's rough state it can drastically affect results and turns DM into a completely different game with consequences for death more like duel.

    I would like to make it 1/2 a point but not sure how to do that yet. Drop your feedback below.


    Big thanks to @RattleSN4K3 - I even stuck with the name he provided (probably off the top of this head, but it's a good working title).

    RedirectReferences=(PackageName="sacrifice_a02-WindowsNoEditor", PackageURLProtocol="https", PackageURL="s3-ap-southeast-2.amazonaws.com/utaunz/sacrifice_a02-WindowsNoEditor.pak")

    https://s3-ap-southeast-2.amazonaws....wsNoEditor.pak

    mutator=/Game/sacrifice.sacrifice_C
    Last edited by the_hack; 03-28-2017, 10:49 PM.
    Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
    www.shockandrockets.com

  • #2
    First of just a note about your idea before I explain how to do such thing or what approach you can do.

    Hmm. You should think about that idea twice. Subtracting the same amount of scoring points from the dying player as adding it to the killer would nullify the whole purpose of scoring points. The average scoring will be at 0 (zero) at max, unless somebody suicide which will than lower the average to a negative value. The idea can be implemented somehow with unequal values but these as to be concepted in order to make any sense. Something like 3 scoring points for a kill, -1 for a death (killed by) and -3 for a suicide. It would somehow work but it wouldn't be the best logic to follow in Deathmatch.

    It's a similar case to the scoring method in Betrayal (for UT3; UT2004 had/has an inofficial gametype). In that gametype each single player had a different score they received by kiling each other (due to using a logic where a lower-score player would receive more for killing a higher-score player and additionally having teams which each sharing a pot you receive by betraying your team members). The scoring was confusing and you couldn't follow the end of the match. Sometimes, you were ranked at the 1st place for about the whole time of the match, and suddently the match ends and a like-4-spots-below player has won the match.


    Now regarding implementing such idea.
    • If you are going to implement it as an mutator...
      1. You need to create a Blueprint based on "UTMutator", and give a proper name such as "Mutator_Sacrifice"
      2. Open that newly created Blueprint and setup the basic mutator (such as name etc.) by opening its "Class defaults" from the top menu and enter:
        • DisplayName
          The name to show in menu
        • Author
          Your name respectively the author(s) of that blueprint
        • Description
          A suited short description stating what the mutator does

        Additionally you can change some other properties but these are not required to have the mutator actually working
      3. Now to the actually implementation which is fairly easy. Look for the green button "Add New" on the left side of your Blueprint window, and select in the dropdown when clicking on that button "Override Function" > "Score Kill"
      4. A node in the event graph of your Blueprint will be created. The first step you should do (which is occasionally mandatory) add a call to your parent function by right-clicking on that node "Event Score Kill" and select "Add call to parent function" from the context menu. Connect every output connection pin from your "Even Score Kill"-node to every input from the "Parent: Score Kill"-node.
      5. Now to the actual implementation of your idea, you need to know the basics of the engine who it works, and of course you need to know what the code base of UT does. There are several things about Blueprint-coding on Youtube, wiki and all that, but UT is different. You actually either have to know how UnrealScript back in UT99-UT2kX-UT3 worked and/or know how UT4's C++ works.

        That said, ScoreKill event is called whenever somebody scores (with a kill) and additionally when someones suicides. By knowing this, you can simply check if the "Killer" paramenter of the event is valid and not the same as the "Other" (the killed player). This way, you have a condition where you only proceed if someone kills another different playyer. Suicidal-subtracing-score is already done by the game code before Mutator::ScoreKill events are called. To prevent crashes, you also need to check if all accessed references are valid.

        Simple check the parameters "Killer" and "Other" and then receive the "Player State" of the other, this reference/object stores the game specific properties such as the Score. Due to "Player State" being of type "PlayerState" which is returned by the field of the "Controller" instance (stored in 'Other'), you need to check whether that object is a specific type you can work with - here "UTPlayerState. This is generally called casting which is only a way to let the compiler/game know, you want to work with that specific class. This can fail when a mod/gametype works with a different class not subclassing/extending UTPlayerState directly, but something like PlayerState (the base class). You need to proceed only if the cast succeeds. Then call the method, which UTPlayerState implements, called "AdjustScore" with the passed value of "-1" to subtract 1 from the existing score.

        The whole implementation looks like this:
      6. The implementation is complete (for a proof of concept). Now you can test it in the game. Switch to your opened map window (like Example_Map) and open the dropdown of the "Play" menu. Open the "Advanced Settings" and scroll down in the opened window (called "Editor perferences") to the input field "Server Game options". There you can enter server commands for the PIE session.


        For adding a mutator, the simple command line argument is: "?Mutator=/Game/My/Path/Mutator.Mutator_C"

        You see you need to have a valid mutator path. You can get this by simply browsing to your mutator Blueprint in the Content Browser, rightclick on that asset and choose "Copy Reference". You will receive something like this when pasting the clipboard content to a text editor.


        Code:
        Blueprint'/Game/Mutator_Sacrifice.Mutator_Sacrifice'
        Adjust that expression by removing the prefix "Blueprint", removing both single apostrophes at the start and the end and finally add the suffix "_C".

        The final mutator string to enter in the server options could look like this:
        Code:
        ?mutator=/Game/Mutator_Sacrifice.Mutator_Sacrifice_C
        If you need to add multiple mutator, you can split the mutators of the "mutator=" value with the delimiter "," like:
        Code:
        ?mutator=/Game/Mutator_Sacrifice.Mutator_Sacrifice_C,/Game/RestrictedAssets/Blueprints/Mutator_Instagib.Mutator_Instagib_C
      7. Hit "Play".

    • For a game mode
      1. You need to create a Blueprint based on "UTDMGameMode", and give a proper name such as "GameMode_Sacrifice"
      2. Open that newly created Blueprint and setup the basic game mode (such as name etc.) by opening its "Class defaults" from the top menu and enter:
        • Display Name
          The name to show in menu

        Additionally you can change some other properties but these are not required to have the gamemode actually working
      3. Now to the actually implementation which is very similar to the mutator implemention. Look for the green button "Add New" on the left side of your Blueprint window, and select in the dropdown when clicking on that button "Override Function" > "Score Kill"
      4. A node in the event graph of your Blueprint will be created. The first step you should do (which is occasionally mandatory) add a call to your parent function by right-clicking on that node "Event Score Kill" and select "Add call to parent function" from the context menu.
      5. Now before connecting the parent-call node, create a sequence and connected the execution/continue pins with the second sequence output and the parent node. Then connect every output connection pin from your "Even Score Kill"-node to every input from the "Parent: Score Kill"-node.

        This way the score is reduced by 1 before the rest, the original logic, is executed. This might be important when thh game considers a player as the winner of the match.
      6. Now implement the same logic like in the mutator class. Connect the first "branch" node of the implementation with the first Sequence node output.
      7. The final implementation looks like this:
      8. Testing. This is different to the mutator testing. You don't need to change settings. Just switch to your opened map window, choose "Settings" > "World Settings". In the "World Settings" panel search for "GameMode override" and selected your game mode from the dropdown.
      9. Hit "Play".








    Btw. there's a Programming section which is better suited for such questions/threads, as it depends where people browse ... in order to receive a good answer/post about it.

    Attachments:
     
    Spoiler
    Last edited by RattleSN4K3; 03-27-2017, 12:36 PM. Reason: Spell check v0.1
    ] Map Scaler Tool | Betrayal for UT4 | No Spawn Protection | No Pickup Timer | BioLauncher (revived) | ForcePickupSpawn | Map cosmetics::P | Safe Spawn::P | Why numbers for Health/Armor suck!::ANALYSIS/CONCEPT
    ] UT3 Addons: NoMoreDemoGuy | PickupRespawnTweak | Mutate Spec | MutePawnSounds | NoPlayerBeacon | Epic FTW | Epic FOCK | TripodSound (... and many more)

    Comment


    • #3
      Hi @RattleSN4K, that's more than I was hoping for, thank you

      I'm keen to try this out and will probably have a few keen players in our small AU community so I will be able to tweak it.

      I wonder if a separate variable that considers frags and deaths might be better, like a star rating based on the ratio.

      In any case it has potential to change the game in a good way.

      I'll report back on my progress with some gameplay vids hopefully.

      Much appreciated, thanks for the time that took, look forward to building this.
      Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
      www.shockandrockets.com

      Comment


      • #4
        updated original with link
        Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
        www.shockandrockets.com

        Comment


        • #5
          Hey. We've had this going on the shock & rockets au server for a day. While I kind of like the crudeness and simplicity of this, going forward we probably want to try this:

          An alternative variable that equals kills minus half of the deaths, or k-d/2. We (puppy and I) think this achieves the best balance out of a bunch of formulas we tested. (Here's a table that shows how a typical DM game with a variety of skill levels might play out using this and other formulas

          https://docs.google.com/spreadsheets...tCrKRL-Tbms1oE


          Again, nfi how to accomplish this, was hard enough just following @RattleSN4K3 's intructions above (lol). However will give it a shot, hopefully with your suggestions.
          Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
          www.shockandrockets.com

          Comment


          • #6
            So instead of making deaths count as -.5 score, which i definately dont know how to do, i thought it might be more possible to keep deaths at -1 and frags at +2.

            This is what I came up with, not really knowing what I am doing, and suprise suprise it doesn't work. I just tried to identify what logic i could in rattlesnake's example and duplicate what i thought was relevant...

            Attached Files
            Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
            www.shockandrockets.com

            Comment


            • #7
              [MENTION=20870]the_hack[/MENTION], I didn't followed this thread closely, but from your last screen it seems to me your ScoreKill goes to Sequence (which only uses one its output of two, for some reason), then from Sequence code switches to Parent:Score Kill, and that it (i.e. rest of nodes left unconnected). Probably Branch should begin somwhere?
              - got sig? -

              Comment


              • #8
                What exo said.

                And, the "Else-branch" from the Branch-node cannot be used like that. The branch is is a if-condition for the exact situtation where someone killed a different person. ScoreKill is also called for the suicide event. And maybe even others. Therefore Killer can be "none" (invalid) or Killer is the same as Other. Additionally, Other could also be "none" but that's not really the case for the UT codebase.

                Code:
                // expression for checking for a suicide
                Other != none && (Killer == none || Other == Killer)
                In Blueprint (too lazy for the image )

                [ Other ]-\..........................______
                ..............[ != ]-------------o.........|
                ...NONE -/..........................| And...o--------------( to branch )------------
                ........................................o_____|
                [ Killer ]-\ .............._____.../
                .............[ == ]----o.......|./
                ...None--/.............| Or...o-
                ...........................o____|
                [ Killer ]-----\......../
                ..................[ == ]
                [ Other ]----/


                If you'd want to add additional 1 (with equals 2 in total, the original gametype already adds 1), you just need to add another "AdjustScore" with 1 as the parater, but this time for the Killer's playerstate.
                [Cast Other.PlayerState] --> [ {Other}.UTPlayerState AdjustScore(-1) ] --> [Cast Killer.PlayerState] --> [ {Killer}.UTPlayerState AdjustScore(1) ]
                ] Map Scaler Tool | Betrayal for UT4 | No Spawn Protection | No Pickup Timer | BioLauncher (revived) | ForcePickupSpawn | Map cosmetics::P | Safe Spawn::P | Why numbers for Health/Armor suck!::ANALYSIS/CONCEPT
                ] UT3 Addons: NoMoreDemoGuy | PickupRespawnTweak | Mutate Spec | MutePawnSounds | NoPlayerBeacon | Epic FTW | Epic FOCK | TripodSound (... and many more)

                Comment


                • #9
                  thanks guys

                  a friend who's more familiar with UE will be taking over (i hope... @puppy). He'll appreciate that help as much as I do


                  repacked for those who want to try. changed link above.

                  i still think the crude version is fun. really punishes the agressive players
                  Maps: DM-Dying_Sun WIP & DM-TokaraSwamp
                  www.shockandrockets.com

                  Comment


                  • #10
                    Minimally more familiar.

                    Hack and I tried the score penalty of 0.5 / death, but on a real server, the bottom players were getting smashed - ending up with -15 or so.

                    So I altered it so that a variable amount was accrued per death based on your score (not position). This ranges linearly from 0.0 if you have the lowest score to 0.3 if you have the highest. You lose a point off your score for every 1.0 accrued.

                    Four desires are in mind:
                    1. To narrow the gap between the top and bottom players in a game so the bottom players do feel some hope.
                    2. To make it closer at the top, especially comebacks when the top player is running away with it.
                    3. To lessen the impact of good initial spawns.
                    4. To reward those with better kill:death ratios

                    That's working well launching from the editor with bots, but I did it as a game mode so I could use a custom PlayerState to keep each player's accrual.

                    How do I package a custom game mode so we can put it on a server?

                    Or would it be better to have some array in a mutator holding the accrurals? Just thought it could get messy if players left/came mid game.

                    Comment


                    • #11
                      Originally posted by a cute puppy View Post
                      How do I package a custom game mode so we can put it on a server?
                      [BP] Sharing Game Mode?


                      Originally posted by a cute puppy View Post
                      Or would it be better to have some array in a mutator holding the accrurals? Just thought it could get messy if players left/came mid game.
                      I've mentioned a way in the_hack's other thread. Typically a mutator supports multiple game types (technically, logically is a different case). For a gamemode you always have to subclasses an existing gamemode and implement your own logic. This is not possible with custom third party game modes (you don't have the sources from).

                      It can get messy but that can be cleaned up. With the code from the other thread, such cleanup could look likes this:
                      (UnrealScript-like syntax, based on UE4/UT4 codebase)

                      Code:
                      event NotifyLogout(Controller C)
                      {
                      	local int i;
                      	Parent.NotifyLogout(C);
                      
                      	// remove entries with an invalid key, where the key is already none
                      	AccumulatedPenalty.Remove(none);
                      
                      	// check if the exiting player still has a valid player state to remove its specific entry of the map
                      	if (C != none && C.PlayerState != none)
                      	{
                      		AccumulatedPenalty.Remove(C.PlayerState);
                      	}
                      	else
                      	{
                      		// otherwise, check all entries if either invalid or not owned anymore by a specific player
                      		for (i=AccumulatedPenalty.Length-1; i>=0; i--)
                      		{
                      			if (AccumulatedPenalty.Keys[i] == none || !IsValid(AccumulatedPenalty.Keys[i].Owner))
                      			{
                      				AccumulatedPenalty.RemoveAt(i);
                      			}
                      		}
                      	}
                      }
                      ] Map Scaler Tool | Betrayal for UT4 | No Spawn Protection | No Pickup Timer | BioLauncher (revived) | ForcePickupSpawn | Map cosmetics::P | Safe Spawn::P | Why numbers for Health/Armor suck!::ANALYSIS/CONCEPT
                      ] UT3 Addons: NoMoreDemoGuy | PickupRespawnTweak | Mutate Spec | MutePawnSounds | NoPlayerBeacon | Epic FTW | Epic FOCK | TripodSound (... and many more)

                      Comment


                      • #12
                        I see - a map keyed by PlayerState - I don't know the lifetime of a PlayerState but I presume they're destroyed at the end of the game? If that's the case there's probably no need to even bother removing it from the map. At least then it'd keep any accumulated penalty if someone did crash and reentered, if that PlayerState persisted.

                        I had a look at the 'Sharing Game Mode' link you provided above (thanks). I was a bit 'oh no...' by the first solution paking it into a map but your suggestion of paking it via command line was ideal. I did try that, got the pak, but on first attempt it wasn't showing up in the game modes. I'll try to work out why when I get some time. Not too sure yet whether to go the mutator road or game mode - it really only applies to DM so I'm not too concerned about not being able to subclass 3rd party game modes.

                        Thanks for the pointers.

                        Comment


                        • #13
                          Originally posted by a cute puppy View Post
                          but on first attempt it wasn't showing up in the game modes.
                          The default name starts with "SKEL_" if you haven't changed the "Display Name" of your game modes' default properties. Occasionally the DisplayName field could be empty and a long time ago those game modes with an empty name were not displayed at all. IIRC this is still the case.
                          ] Map Scaler Tool | Betrayal for UT4 | No Spawn Protection | No Pickup Timer | BioLauncher (revived) | ForcePickupSpawn | Map cosmetics::P | Safe Spawn::P | Why numbers for Health/Armor suck!::ANALYSIS/CONCEPT
                          ] UT3 Addons: NoMoreDemoGuy | PickupRespawnTweak | Mutate Spec | MutePawnSounds | NoPlayerBeacon | Epic FTW | Epic FOCK | TripodSound (... and many more)

                          Comment


                          • #14
                            Thanks - that was ok - I'd used the wrong UT4 build number when paking. Fixed that up and all is good.

                            Is there an easier place to find this version number other than watching a log of a share from the editor?

                            Comment


                            • #15
                              Originally posted by a cute puppy View Post
                              Is there an easier place to find this version number other than watching a log of a share from the editor?
                              Other than opening the log file, there's no easier way to find out the exact version. Searching the source code can lead to varios wrong numbers, and this is heavily changing where to look at.

                              Just start a the game and open your log file:
                              Code:
                              %userprofile%\Documents\UnrealTournament\Saved\Logs\UnrealTournament.log
                              The "network version" is stated several times in the first couple of lines. But most likely the correct one is always printed in the line with "GetLocalNetworkVersion: CL: ", although IIRC the network can be overridden and it is stated with a "warning" in the log. This can happen if they release a hotfix.
                              ] Map Scaler Tool | Betrayal for UT4 | No Spawn Protection | No Pickup Timer | BioLauncher (revived) | ForcePickupSpawn | Map cosmetics::P | Safe Spawn::P | Why numbers for Health/Armor suck!::ANALYSIS/CONCEPT
                              ] UT3 Addons: NoMoreDemoGuy | PickupRespawnTweak | Mutate Spec | MutePawnSounds | NoPlayerBeacon | Epic FTW | Epic FOCK | TripodSound (... and many more)

                              Comment

                              Working...
                              X