leaguevine / leaguevine-ultistats

MIT License
18 stars 4 forks source link

Tracking a game! #7

Closed cboulay closed 12 years ago

cboulay commented 12 years ago

Game detail view should have a button to track it / enter stats. Easy enough. Then the fun/extremely difficult work begins.

There are some details required from the user before the game can begin. -Who is pulling to start the game? -At what score is half-time? This can be inferred from a game-to score but know that any game-to score is not a hard rule for what the final score will be (i.e. run out of time and/or win-by-two).

There are at least 2 views. Game action, player substitution.

There is a lot to work on here but I will come back to this issue after I've taken care of some others first.

cboulay commented 12 years ago

I put a skeleton module in place. I really can't do much more until I have some data to play with. In particular I need players on teams. So I will work on screens to enter that data before I work on the game tracking screen.

mliu7 commented 12 years ago

Roger and I spent a bunch of time on designing the UI for the game tracking screen and here is a mockup of what we came up with:

https://docs.google.com/presentation/d/1VjpPtkmoR23q1MzoSfcNT82SvwVBWQZjNw-MXeWkcnk/edit#slide=id.p

mliu7 commented 12 years ago

In addition to that google doc, here are some more detailed descriptions about what button combos should be pressed and what buttons show up when certain events need to be entered.

Pull - The screen of the pulling team is shown. The player prompt is "Who pulled?". Tapping a player's name creates a pull event (type 1) and navigates to the picked up disc screen.

Picked up disc - The screen of the receiving team is shown. The player prompt is "Who picked up?". No buttons are highlighted. Tapping a player's name creates a picked up disc event (type 10). The player prompt is changed to "Complete pass to: " and the "completion" button is highlighted.

Complete pass - The player prompt is "Complete pass to: ". The "Completion" button is highlighted already by default. Tapping the "Completion" button does nothing, because it is assumed to be pressed anyway. It is there for consistency because the other types of passes are on the right hand side as well. Tapping a player's name creates a complete pass event (21).

Throwaway - This event starts from the regular "Complete pass" screen with the "completion" button highlighted. It starts from this screen because "completion" is the default pass type. Tapping the "Throwaway" button makes the player area change to the other team, with the player prompt changing to "Who picked up?". All buttons lose their highlighting. A throwaway event is created (type 32).

Dropped Pass - This event starts from the regular "Complete pass" screen, identically to Complete Pass and Throwaway above. Tapping the "Dropped Pass" button causes the "Dropped Pass" button to be highlighted, and all other buttons to lose their highlighting. The Player prompt is changed to "Who dropped the pass?". Clicking on either a player or "unknown" causes a drop event to be created (type 33). The screen then changes to the other team's Picked Up Disc screen.

D'ed pass - This event starts from the regular "Complete pass" screen, just as Dropped Pass, Throwaway, and Complete pass do. Clicking on D'ed pass causes the D'ed pass button to be highlighted, all other buttons to lose their highlighting, the buttons in the player area to be changed to the other team's players, and the player prompt to be changed to "Who D'ed the pass?". Tapping a player's name or "unknown" causes a D event to be created (type 34). The screen then changes to the defensive team's Picked Up Disc screen, with no elements highlighted.

I'll lay out some more event types soon, but this is enough to give an idea of how it will work.

mliu7 commented 12 years ago

Also, do you have a plan for how you want to maintain the game tracking state? I'm wondering if I should begin working on this or if you'd prefer I wait until you roll out some initial code.

cboulay commented 12 years ago

you can alreadysave. that's what the localstorage plugin is for.

cboulay commented 12 years ago

My goal is to be able to correctly show/hide the playerArea knowing only the last event in the gameevents collection. I also want to be able to properly interpret a player tap knowing only the last event in the gameevents collection. This is easy enough for passes, pulls, pick-ups, throwaways (unless we want to record intended receiver... I don't). It gets more difficult with some of the other actions. I think I will need the 'drop' or 'd' buttons to create incomplete events while I wait for the user to press the button for the second player involved. If I can achieve this, then it becomes MUCH easier to undo an event. Also, this would nicely separate the view from the models. The views would just be dumb renderers and click detectors.

For presentation and user interaction, the logic seems like an action button determines the meaning of the NEXT play. Similarly, the prompt is updated based on the action button pressed. Considering that, should the player buttons be on the right and the action buttons on the left, so it reads like Action by/to Player? And maybe we can make them all "by" if we think about it like "received by", "dropped by", "D'd by", "Picked up by", "Pulled by". The only one that doesn't fit is throwaway because we already know who threw it away (the last receiver!) so it will just jump straight to the "picked up by" screen.

Does that make sense?

cboulay commented 12 years ago

There will be a bias in determining whether a pass was D'd or thrown away depending on who is recording the stats. Everyone likes to think they are in control of their own fate and thus they lose a game because they played poorly, not because the other team was better. Therefore turnovers from "our" throws that someone on their team might touch are always throwaways and turnovers from "their" throws touched by us are always Ds (no matter how amazing the defensive play or how poor the throw was, respectively).

How can we eliminate this bias? Should a D automatically include a throwaway? (It does in American football). If so, we might want to consider removing "D'd" from the offensive actions and have another set of defensive actions that become available following a throwaway, such as "intercepted by", "knocked down by", "picked up by", defaulting to "picked up by" if no other action is pressed.

cboulay commented 12 years ago

Sorry for rambling... If we do that, then maybe we can add "stall" below throw away instead of "D"

The server would also have to know that a knockdown or D are not changes of possession, only the preceding throwaway is. That might not be intuitive to users of the API. What do you think?

mliu7 commented 12 years ago

Good thoughts on how to keep track of the game state. The idea about keeping track of partial events sounds effective. Are you going to implement this or should I get working on it? (I'd prefer you did since you know that part of the code so well :P)

I like the logic behind having the actions on the left and the player buttons on the right. For the general case of throws, it matches the english language better if we do it this way. I plan on making this change soon.

Yes, there will be a bias like you said. I'd like to overcome this by encouraging users to click the "D'ed pass" button. I could put some small, light text under "throwaway" that says something like "(Not touched by D)". Right now, a D automatically includes a turn and incomplete pass by the thrower. I think this is adequate if the definition of a "throwaway" is: an incomplete pass that was uncatchable by the receiver and not D'ed by a defender. I don't think there is a universal definition of throwaway. If this definition changes, we will still have all of the data of who threw D'ed passes stored in the database so we can re-calculate the stats later.

I'm opposed to having "Stall" on the main screen simply because it is a very uncommon event and I think only the most common events should be there. We could add it to Misc.

cboulay commented 12 years ago

It's good to know that a D event automatically includes a throwaway. This makes things a bit easier, and I don't have to include the extra defensive buttons. As for getting people to only use 'throwaway' when it has not been touched, we could use "untouched throwaway" on two lines, both words of the same font (9 letters and 10 letters), though the font will have to be somewhat smaller than the other buttons.

cboulay commented 12 years ago

Oh, and yes I will take care of the game state and button logic. This weekend is a bit busy but I should have it done in a few days.

mliu7 commented 12 years ago

Good call on the "Untouched throwaway" action. That makes things extremely clear.

Thanks for taking care of the game state and button logic. I'll focus on other stuff.

mliu7 commented 12 years ago

I just committed the new layout revision, and in this new one it makes sense for the player buttons to NEVER remain highlighted after they are clicked. The player buttons are now the recipients of actions. In order to make it clear to the user who has the disc, we will make the player's name very noticeable in the upper left. Further, the user who has the disc will have their button greyed out and deactivated so you cannot have them pass to themselves. I've updated my previous comment on event types accordingly.

Continuing on the Event types from that other comment, I'll add the rest of the types described by the buttons we have:

Score - This event starts from the regular "Complete pass" screen, just as Dropped Pass, Throwaway, and Complete pass do. A user clicks on "Score" and then the score button is highlighted and the player prompt changes to "Who caught the score?" After a user clicks on a player's name or unknown, a score event (type 22) is created. The page then changes to the other team's Picked Up Disc screen.

Unknown Turn - This button shows up when a user clicks on "Misc". As soon as "Misc" is tapped, all of the player buttons become greyed out and cannot be tapped. Clicking "unknown turn" causes a turnover event (type 30) to be created without it being attributed to any players. The page then changes to the Picked Up Disc screen for the defensive team.

Timeout - Similar to Unknown Turn, this is only available after clicking on "Misc", and all player buttons will be greyed out at that point. Clicking "Timeout" causes a timeout (type 90) to be created. The previous action area gets updated as usual, but nothing else happens.

End of Period - Similar to Timeout and Unknown Turn, this is only available after clicking "Misc" and the player buttons are greyed out. Clicking "End of Period" causes all of the action buttons to be replaced by four buttons that say "End of first quarter", "Halftime", "End of third quarter", "Game Over". Clicking one of these creates the appropriate event (94, 95, 96, or 97). The "Game Over" button will take the user back to the game detail page. The other three buttons will take the user to the substitution screen.

Stall - This is also only available after clicking "Misc" and the player buttons will be greyed out. Clicking "Stall" will cause the stall button to become highlighted, the player area to become clickable again, and the player prompt to be "Who was on the mark?". After a player or unknown is clicked, a stall event (type 51) is created. It then goes to the Picked Up Disc page for the defensive team.

Foul/Violation - I've removed this button for now, and we'll add it later. It is pretty complicated because of all the different types of fouls/violations and the fact that either offense or defense can commit them at any time. We'll implement this one last and come back to it then.

Injury - This is also only available after clicking "Misc" and the player buttons will be greyed out. Clicking "Injury" will take the user to the substitution screen where a player can change the lineups for the teams. Once the changes have been made and the user clicks "Done", two types of events will be created - Injury Substitution In (type 82) and Injury Substitution Out (type 83). The page then goes back to the regular game tracking page at the exact state it was at before injury was clicked.

cboulay commented 12 years ago

I'm writing this out mostly for myself but please let me know if you see any issues.

Button results are grouped by button because that's how they will be coded.

StatePressEventGoTo
DefaultPlayerPassDefault
Pickup?PlayerPickupDefault
Dropped?PlayerDrop _Turnover_ ->Pickup?
D'ed?PlayerDPickup?
Scored?PlayerScoreSub Screen + Pulled?
Pulled?PlayerPull _Turnover_ ->Pickup?
DefaultUntouched ThrowawayThrowaway _Turnover_ ->Default
DefaultDropDrop _incomplete_ Dropped?
DefaultD'edD _incomplete_ _Turnover_ -> D'd?
DefaultScoreScore _incomplete_ Scored?
DefaultUnknown TurnTurnover _Turnover_ ->Pickup?
DefaultStallStall _Turnover_ ->Pickup?

What do we do if the user presses D'd which then causes a turnover and asks "who D'd?" but really they wanted dropped pass? Should they have to complete the play or should pressing undo in this incomplete state undo this half-event? If "Undo" undoes a half-event, does it confuse the user if "Undo" also undoes a complete event should the user press the D'ing player before pressing undo?

cboulay commented 12 years ago

As a reminder to myself: Instead of using two looping appends within the TrackedGame.Views.SubTeam, it might be better to insert two copies of the list view (not yet created), then let the listview do the direct add/remove of its child views. It's too bad that I can't reuse the TeamPlayer module's ListView and ItemView but the implication of tapping a view is very different.