PROJECT: Scripting to detect player score changes/kills

Discussion in 'Halo and Forge Discussion' started by Yumudas Beegbut, Dec 11, 2017.

  1. Yumudas Beegbut

    Yumudas Beegbut Legendary
    Wiki Contributor Senior Member

    Messages:
    393
    Likes Received:
    352
    My health has crapped out too much to allow me to get to making helpful game mode prefabs for objectives, game mechanics, player scoring, player IDs, etc etc.

    So I'll try dumping one (really useful) game mode prefab idea here on Forgehub as a project any of us can work/help/comment on. Along with some script ideas and info that can help solve this thing. Sorry about the wall of text, but I'm not really sorry at all.

    If this works out, we can do much, much more and rev up H5 Customs.

    PROJECT: TRACK PLAYER SCORE CHANGES (AND MORE)
    We can track player scores using Player Numbers and the Game Values section in the Number Change action. If we use a heartbeat timer to constantly check for player score changes, we'll constantly know when players have scored points. This project will open up all the things we can do if we can track player score changes:
    • In game modes based on Minigame you can add player scores to the team scores, which doesn't happen by default
    • In Slayer and Minigame, you can detect player kills
    • You can also track other useful info from the Game Values section:
      • Team (score)
      • Health (current), Health (max), Health (ratio) - also for objects
      • Shields (current), Shields (max), Sheilds (ratio) - also for objects
      • Players (current), Players: Team (current), Teams (current) - these can be used to know if players leave or new players join!!!
      • Spawn: Order - also for objects
    IDEA + POTENTIAL SCRIPTS FOR DOING THIS

    Overview

    This is the idea, but it has to be tried out and debugged. If we're lucky it'll be all we need. These scripts use each player's {november} and {oscar} numbers to track individual score changes. What you do with the player score is determined by Script #S3 below.
    • {november}: Player number used to calculate score changes (NEW_SCORE - OLD_SCORE)
    • {oscar}: Player number that holds the player's old score from the last check
    • This example adds the points when a player's score goes up because it checks for changes Greater Than Constant 0... Use Greater Than Constant -9990 to include negative scores
    Control Brain
    The Control Brain continuously sets ALL player {november} numbers to -9999 to start a chain reaction that happens in the next game tick (1/60th of a second later).
    Timer 1.00 0.10 //// use whatever timing/controls needed
    A1) Number Change: Scope=Player, Channel={november}

    NUMBERS=Players[add]
    Force Dirty=ON, Constant=-9999

    Score Brains
    There needs to be one of these brains per player, so use 16 to be sure or use less if you're sure there won't be more players than brains. The scripts can't be combined to use less and they need to be in this order... Probably.

    Each brain picks one player (via Select Last: 1) to handle by changing her/his {november} to -9998.
    Number Check: Scope=Player, Channel={november}, Equals Constant=-9999
    A1) Number Change: Scope=Player, Channel={november}

    NUMBERS=EXTRA[add], Select Last: 1
    Increment, Constant=1

    Copy that player's score to {november} then subtract the old score {oscar}. Now {november} has the amount the player's score has changed since last check.
    Number Check: Scope=Player, Channel={november}, Equals, Constant=-9998
    A1) Number Change: Scope=Player, Channel={november}

    NUMBERS=EXTRA[add]
    Set, Source=Game Value, Player Score, Object=ACTIVATOR
    A2) Number Change: Scope=Player, Channel={november}
    NUMBERS=EXTRA[add]
    Decrement, Source=Number, Scope=Object, Object=ACTIVATOR
    Scope=Player, Channel={Oscar}

    If the player's score has increased (so {november} > 0), this example script will add that amount to their team's score. This can be changed to whatever you need to do when a player's score increases. Or you can add additional actions to do more, like for Slayer/Minigame {novermber} has the points the player gained for kills.
    Number Check: Scope=Player, Channel={november}, Greater Than, Constant=0
    A1) Score Change: Team, SCORERS=EXTRA[add]

    Increment, Source=Number, Scope=Object, Object=ACTIVATOR
    Scope=Player, Channel={November}

    Finally set this brain's selected player's {november} number to -9997 so this player won't get selected by other brains for the rest of this check/game tick since they will also check for -9999, -9998 and > -9990. Then copy the player's score to {oscar} so it'll be the old score for the next score check.
    Number Check: Scope=Player, Channel={november}, Greater Than, Constant=-9990
    A1) Number Change: Scope=Player, Channel={November}

    NUMBERS=EXTRA[add]
    Set, Constant=-9997
    A2) Number Change: Scope=Player, Channel={oscar}
    NUMBERS=EXTRA[add]
    Set, Source=Game Value, Player Score, Object=ACTIVATOR

    I used big negative numbers like -9999 to make sure player scores will always be higher than these number codes for {november}, but you can use smaller ones as long the codes you replace -9999, -9998 and -9997 with are bigger negative numbers than the -9990 replacement. Ex: -999, -998, -997 and -990.
     
  2. Soldat Du Christ

    Soldat Du Christ Legendary
    Senior Member

    Messages:
    1,530
    Likes Received:
    2,353
    Wow, i didn't read any of that but good work!
     
    CertifiedChamp likes this.
  3. ExTerrestr1al

    ExTerrestr1al Forerunner
    Senior Member

    Messages:
    2,387
    Likes Received:
    2,515
    Awesome! I havent read all of that yet, but being afellow text waller, i certainly will.

    First thing that comes to mind is that detecting a chang in score is not hard at all. You just get two scripts checking the same number on different intervals. Anytime they are not equal is a trigger for doing a thing.
     
  4. Yumudas Beegbut

    Yumudas Beegbut Legendary
    Wiki Contributor Senior Member

    Messages:
    393
    Likes Received:
    352
    Thanks so much. :|

    Yeah I can't learn to not explain things clearly and precisely using a text wall... which ends up being counterproductive since people often interpret language more emotionally than logically.

    TL;DR = dumfks

    The approach above uses 1 interval and 2 numbers: 1 to store the old value and 1 to calculate the difference.

    There are several issues that come up when continually tracking changes for all players' scores & I'm pretty sure this approach will work. It's worth studying. And making.
    • Keeping track of multiple players gets tricky, especially making sure calculations are done for each player while not mixing them up
    • Waiting for the next tick for a Number Check to detect a Number Change can take several game ticks to resolve and you need to know which player is which
    • Simultaneously changing the same number channel for all the players lumps them all together when you select them with EXTRA [add]
    • I forget what else were hurdles
     
  5. ExTerrestr1al

    ExTerrestr1al Forerunner
    Senior Member

    Messages:
    2,387
    Likes Received:
    2,515
    explain that Extra [add] criteria... i've never understood what that does or how it's useful... I use all the other ones though...

    Dealing with game ticks gets slightly easier if you put things on separate scripts so they are each action 1 on their own script (something I'm sure you know) vs being 1 & 2 on the same one.

    However, I'm having a hard time imagining that there is even a problem, but that often happens when I think I can do something easily, go into forge and try it, then figure out there are major considerations I haven't thought of or no one has ever found before!

    The way I THINK it should work... (EDIT: Note, that this uses one global variable per person, rather than two. I err on the side of using more objects vs more channels/vars/etc. it keeps things open for other complex scripts someone else may want to insert into the same map)

    • Set up one object like an invis ball joint or script brain. One per person (sucks, but probably necessary).
    • Each brain would calculate an individual player's score on an interval. Stores as object's personal number.
    • Each brain has a unique global variable it is also constantly updating on a different interval.
    • Each brain has a script comparing when they are not equal, triggering something else. (If intervals are different enough, there should ALWAYS be an instance when the shorter one is different than the longer one. Fine tuning will be interesting, but hsould work)

    You can assign players a label each in a fast and clean way, which I've outlined in my Flare thread... I'll copy the relevant parts back over here... then each number is counting number of players with a label assigned to that number.

    It should then be possible to know almost exactly when and who makes a score change. Unless of course, there is a major consideration I haven't though of yet.

    (one major thing will be cleanup of a label previously used by a player who leaves the game. That needs to be made available again for a new joiner. But, I think that shouldn't be too hard either. When the count for that label equals zero, make the label assignment thing happen again if it needs to. It might be easy to set it up in a way that will just automatically assign anything not already assigned.)

    EDIT: Here is the label assignment post -- if you don't want any of the history, scroll down to the "here's how you should do it" portion.

    https://www.forgehub.com/threads/wi...-in-on-development.156852/page-2#post-1703160
     
    #5 ExTerrestr1al, Dec 13, 2017
    Last edited: Dec 13, 2017
    Yumudas Beegbut likes this.
  6. Yumudas Beegbut

    Yumudas Beegbut Legendary
    Wiki Contributor Senior Member

    Messages:
    393
    Likes Received:
    352
    Oh here's a Google Sheet that has all the Conditions & Actions properties and options spelled out. And some other useful stuff: https://docs.google.com/spreadsheets/d/1vNcpgv4Ime2no1cy8vLqUWzU08qXqqKq0TLRyjOR5yQ/edit?usp=sharing

    I have to check to see if you're right about using the Brain's object Number instead of 1 player Number {channel}... Seems like there might have been something didn't work there. I'm down with saving a Number {channel}. I think it might have something to do with needing Number Check for both the object and player channel to trigger while keeping the old player score unchanged...

    EXTRA depends on the Condition's context, similar to ACTIVATOR. There are small descriptions of EXTRA in the help text when the Condition is selected, but they're more like vague clues. I think these are correct descriptions:
    • Boundary Check: EXTRA returns all the qualifying objects inside the zone, mostly useful for Continuous since they changed ACTIVATOR to only return objects that just crossed the boundary
    • Number Check: EXTRA returns all objects (or channels) whose number changed and met the criteria when the script started
    You jarred my memory about some hurdles. Here's part of the problem solving process for this crap, some of which you covered:
    • TL;DR: We have to use Number Change on a player number {channel} so it triggers Number Check to access player Numbers or Game Values... and it's tricky to change a Number {channel} for all players at once
    1. The only Actions that can read Numbers or Game Values are Number Change, Score Change and Spawn Order Change
    2. The Object property we have to use to access player Number/Game Values only shows up when the Condition has ACTIVATOR or EXTRA mod-selections and it only has options of THIS and ACTIVATOR
    3. ACTIVATOR for the Object property is the same as EXTRA for the Number Change Action
    4. Since players can't be the THIS object, the only way to select their Numbers/Values is with Conditions that give us the ACTIVATOR or EXTRA mod-selections
    5. Conditions with ACTIVATOR/EXTRA: Interacted, Boundary Check, Number Check, Message Received, Power Check (not sure if Message Received and Power Check are usable without first using Interacted or Boundary Check)
    6. Since Interacted and Boundary Check require players to trigger them and Message Received and Power Check can't be initiated by players, that only leaves Number Check when we want to access player Numbers/Values any time
    7. To use Number Check so we can read player Numbers/Values with Number Change, Score Change and Spawn Order Change we have to change/dirty those Numbers with Number Change on the game tick before
    8. If there's more than 1 player number that qualifies for a Number Check, you'll still only read 1 (random?) of their Number/Values in Number Change, so you often have to make sure only 1 player Number triggers the Number Check at a time... and remember that Number Check can't use mod-selection!
    9. That means you have to A) use different player Numbers for each player, B) use the same player Number but only change 1 each game tick, or C) trigger the same Number for all players but change 1 at a time with a script so that it's the only one that qualifies for the Number Check script that immediate follows it... which means you need a set of scripts for each player
    10. Or you have to create a more complicated system keeping unique IDs or labels for players and make sure the object with the scripts handles only 1 player at a time
    11. Show-off Note: the scripts above get rid of the unique ID requirement AND all the Brains have the exact same scripts... we might not need IDs at all, but I'd wager they'll still be useful
    12. If you want Number Check Conditions for different Numbers (i.e. different channels or objects) to trigger during the same game tick, you have to change/dirty all of them the game tick before
     
    #6 Yumudas Beegbut, Dec 13, 2017
    Last edited: Dec 13, 2017

Share This Page