# Party sessions of short rounds (party.rounds) A party game made of short rounds played one after the other by 2 to 8 contestants, local players or bots. Each round is a data document; the kit runs the intro card, the round, the placement, the points and the final podium. Readable offline: `gripforge docs party-rounds`, or the MCP tool `gripforge_docs` (topic `party-rounds`). ## What it is for A session goes through the phases `lobby`, `intro` (everybody held on their start, the rules shown), `play`, `results` (points by placement), the intro of the next round, and finally `podium` and `done`. A round says how it is won (`goal`), how long it lasts, what the arena looks like and what happens in it. The kit moves the bots, the local players 2 to 4 and the pushes, places the contestants and scores them. Player 1 is the character of the game. The look of the cards, clock, scores and podium is the presentation module (a fragment of the web UI); the models come from the asset slots `party_bot`, `party_pickup`, `party_hazard`, `party_platform` and `party_finish`. ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "party.rounds" } gripforge_gamekit_configure { project_id: "gkp_…", id: "party.rounds", config: { "contestants": 4, "humans": 1, "rounds": ["shrinking_ring", "gem_rush"] } } ``` It requires `input.actions`, `world.ground` and `game.engine`. Add the rounds to the `party_rounds` collection of the project; with `rounds` empty, all of them are played in collection order. ## First example Three bots and two rounds, with the intro, results and podium pauses at 0: ```json { "id": "a", "name": "A", "goal": "most_points", "seconds": 5 } { "id": "b", "name": "B", "goal": "last_standing", "seconds": 5, "arena": { "size": 4 } } ``` In round `a`, `party.session.award(id, 5)` gives one contestant points and `endRound()` places everybody: 10 points for first, 6 shared by the two tied for second. In round `b`, two `eliminate(id)` calls leave one contestant standing, and the session reaches `done` with the standings kept in `state().results` and `standings()`. ## The round document | Field | Meaning | |---|---| | `id`, `name`, `goal` | required. `goal` is `last_standing` (the later out, the better), `most_points` (pickups collected), `first_to_goal` (finish order, then distance left) or `survive` (like `last_standing`; ends when time is up or all are out) | | `rules` | text of the intro card | | `seconds` | length, 5 to 600 (default 45) | | `arena` | `shape` `circle` or `square`, `size` (radius or half side, default 12), `edge` `fall` (past the edge is out) or `wall`, and a shrink: `shrinkTo`, `shrinkStart`, `shrinkSeconds` | | `pickups` | `count` on the floor at once, `value` (default 1), `respawn` (default true), `radius` | | `finish` | `at` `[x, z]` from the centre, `radius` | | `hazards` | falling waves: `every`, `warning`, `radius`, `perWave`, `aim`, `effect` `out` or `knock` | | `push` | `force` (m/s), `reach`, `cooldown` | | `start` | `ring` around the centre or `line` side by side at the back | | `points` | points by placement for this round (default: the session's) | | `onStart`, `onEnd` | trigger actions run when the round starts and ends, to drive other kits | A tie shares the better place and the next place is skipped. ## Settings and defaults | Setting | Default | Meaning | |---|---|---| | `contestants` | `4` | players in the session, 2 to 8: the humans, then bots | | `humans` | `1` | local players, 0 to 4; player 1 is the character, players 2 to 4 use the numeric keypad | | `names`, `colors` | generated | per seat | | `rounds` | `[]` | ids of the `party_rounds` documents, in order; empty plays all | | `points` | `[10, 6, 3, 1]` | points by placement | | `introSeconds`, `resultsSeconds`, `podiumSeconds` | `4`, `5`, `6` | length of each phase | | `autoStart` | `true` | start with the game; off: call `start()` or use the action `party_start` | | `center` | `[0, 0, 0]` | where the rounds are played | | `botSpeed`, `humanSpeed` | `5.5`, `6` | m/s of the bots and of players 2 to 4 | | `endGame` | `true` | the podium ends the game: `game.won` if player 1 shares first place, else `game.lost` | ## Services, events, variables, hooks - `party.session` (service): `start()`, `state()`, `contestants()`, `standings()`, `round()`, `placements()`, `award(id, n)`, `eliminate(id)`, `finish(id)`, `push(id)`, `endRound()`, `skip()`, `arenaSize()`. - `party_start`, `party_award`, `party_end_round` (actions) and `party_finished`, `party_round_is` (conditions) for scripts. - `party.started`, `party.round_intro`, `party.round_started`, `party.out`, `party.collected`, `party.finished_line`, `party.pushed`, `party.round_ended`, `party.podium`, `party.finished` (events); `party.out` has a `cause` (`edge`, `hazard` or `script`); `party.round_ended` carries the `placements`. - `game.won`, `game.lost` (events): sent at the end of the podium when `endGame` is on. - `party.phase`, `party.round`, `party.rounds`, `party.round_name`, `party.timer`, `party.leader` (variables). - `party.push`, `party.p2_push`, `party.p3_push`, `party.p4_push` (input actions) and the axes `party.p2_x`, `party.p2_y` (and the same for players 3 and 4). - `round.start` (hook): the intro is over; `seconds` mutable; cancelled, the round is skipped without points. - `round.award` (hook): before round points; `amount` mutable; cancellable. - `round.score` (hook): per contestant at the end of a round; `points` mutable. - `match.end` (hook): before the podium ends the game; `won` mutable; cancellable (the game does not end). ## Hooks and modding A mod can change `contestants`, `names`, `colors`, `rounds`, `points`, the three durations and the two speeds, and add, patch or remove `party_rounds` documents. `autoStart`, `center`, `humans` and `endGame` stay the game's own choice. The four hooks above let a rule change the length of a round, double the points of a pickup or rewrite the final result. ## Engines The web and the native Rust host run the same session. The cards, the clock, the scores and the touch push button are drawn by the presentation module of each host. ## When it does not do what you expect - The session never starts: `autoStart` is off (call `start()`), or the collection `party_rounds` is empty. - A round is missing: its id is not listed in `rounds`, or a `round.start` tap cancelled it. - Nobody scores in a `most_points` round: the round has no `pickups`, or no one calls `award`. - The game does not end after the podium: `endGame` is off, or a `match.end` tap cancelled it. ## Limits Local players share one screen and one keyboard (player 1 on the usual keys, players 2 to 4 on the numeric keypad). The rounds are built from the fields above; a rule beyond them is written as `onStart` and `onEnd` actions or hooks. ## Versions Kit 1.1.0, service `party.session` 1.0.0. 1.1.0 added the hooks and the script verbs.