Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions projects/Games/docs/HOLDEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Hold'em is a **player pot**, not a house game. Guild auto-dealer, staff mint, an
## Rules

- No-limit Hold'em. Stacks are chips on the felt.
- 2+ players to start a hand (seated in `actives`). Idle shoe click by a seated player deals.
- 2+ players to start a hand (seated in `actives`). At a cash table, an idle shoe click by a seated player or the host deals. At a [tournament](#tournaments) table only the host or staff deal.
- Button is `table.dealerId()`. First player to chip in is the button. When they leave or log out, the button passes to the next seated player in seat order (`actives` insertion order). After a finished dealt hand (fold-win), rotate around that circle.
- Blinds default from `games.yml` `poker.blinds.small` / `big`. Each table can change them in options. Displayed on the hologram; not posted.
- Blinds default from `games.yml` `poker.blinds.small` / `big`. Each table can change them in options. They are shown on the hologram and posted at the start of each hand: heads-up, the button posts the small blind; otherwise the seat after the button does, and the next seat posts the big blind. Preflop action starts after the big blind. A player who cannot cover a blind goes all in for what they have.
- No straddles, bomb pots, or other variants.
- Optional burn cards: later.
- Side pots: a short call is in for that amount; extra chips from others make a side pot at showdown.
Expand All @@ -30,7 +30,7 @@ One seated: shoe still draws. Two seated, seated click: holes deal, shoe locked.

## Betting

Preflop chat: **check**, **call**, **fold**, **raise** (same path as blackjack hit/stand). Raise is chips already on this street above the call, then the word. No `/wager` commit for Hold'em. Last player standing wins without ranking: session ends, button moves. Still no blind posting.
Preflop chat: **check**, **call**, **fold**, **raise** and **allin** (`all in` also works), or `/games bet <word>` (same path as blackjack hit/stand). Raise is chips already on this street above the call, then the word; check or call with chips above the bet counts as a raise. At a cash table, stakes go on the felt only on the current player's turn. **All in** stakes the player's entire remaining coins (or tournament stack). No `/wager` commit for Hold'em. Last player standing wins without ranking: session ends, button moves.

## Community cards

Expand All @@ -42,12 +42,35 @@ When river betting matches, remaining holes are shown, best 5-card Hold'em hand

## Short calls and side pots

**Call** with fewer chips than the bet is allowed: they are in for that amount and skip the rest of the street. **Raise** still needs more than the bet. At showdown, pots are layers by total invested (all streets). Folded chips stay in the pots they paid into. No extra chat word. Still no blinds posted.
**Call** with fewer chips than the bet is allowed: they are in for that amount and skip the rest of the street. **Raise** still needs more than the bet. At showdown, pots are layers by total invested (all streets). Folded chips stay in the pots they paid into. No extra chat word.

## Table options

Place and sneak-edit: small/big blinds and Shoe vs Round shuffle. Defaults from `games.yml`. Still not posted. `ROUND` reshuffles at hand start (already). Later: optional burns.
Place and sneak-edit: small/big blinds and Shoe vs Round shuffle. Defaults from `games.yml`. `ROUND` reshuffles at hand start. Tournament blinds also start from these values.

## Test

Place poker 5/10 Round: hologram blinds + Round. Edit 0/0: no blinds line. Old JSON without fields: yaml blinds. Non-owner sneak still flushes. Blackjack options unchanged.

## Tournaments

Tournament settings live on the table with its other house settings; the rules are in [PokerTournament.java](https://github.com/TF-Minecraft/Games/blob/main/src/main/java/net/tfminecraft/games/game/PokerTournament.java) and the commands in [PokerCommands.java](https://github.com/TF-Minecraft/Games/blob/main/src/main/java/net/tfminecraft/games/command/PokerCommands.java). `/games poker` commands need `games.bet` and act on the nearby `poker` table. The table host is the player who placed the deck; "host" below also covers staff with `games.admin` or `games.autodealer.staff`. The host stays the same as the button rotates.

| Command | Who | Behaviour |
|---------|-----|-----------|
| `/games poker [status]` | Anyone | Show buy-in, starting chips, rebuys, ante and blind interval. |
| `/games poker configure <buy-in Denars> <starting chips> <max rebuys> <ante chips> <blind minutes>` | Host | Only at an idle table with no money on it and nobody bought in. Buy-in `0` selects cash play. Limits: buy-in 0 to 1,000,000; starting chips 1 to 1,000,000; rebuys 0 to 100; blind interval 0 to 10,080 minutes. Starting blinds come from the table options menu. |
| `/games poker buyin` | Player | Pay the buy-in before the first hand and receive the starting stack. |
| `/games poker rebuy` | Busted player | Between hands, within the configured rebuy limit. |
| `/games poker start` | Host | Deal the next hand, also done by right-clicking the shoe. The host does not need to buy in. Needs two players with chips. |
| `/games poker bet <chips>` | Current actor | Put extra chips into the pot, then say `raise` or `check`. |
| `/games poker kick <player>` | Host | Between hands. Removes a registered player who is online. |
| `/games poker finish` | Host | Between hands, once only one positive stack remains: pays that player the Denar prize pool. |

Play:

- Chips are counters on the table. They never enter player inventories or Denar payouts; the buy-ins are held in the table ledger as the prize.
- Each hand collects the ante from every seat as dead money, then posts the blinds. With a blind interval above `0`, blinds double every interval after the first hand, and each new level is collected from the next hand dealt; `0` keeps them fixed.
- `call` takes the chips needed to match automatically; a short stack goes all in. Players with no chips sit out until they rebuy.
- Leaving or being kicked before the first hand refunds the buy-in. After play starts it forfeits the entry.
- When Games is disabled (server stop or plugin reload), tables reset to idle: tournaments end, Denar stakes still on the table return to their owners through the table's refund path (dropped at the table for offline owners), and chip stacks are cleared. Tournament settings persist.
9 changes: 7 additions & 2 deletions projects/Games/docs/SYSTEM.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ All paths under `plugins/Games/` on the server.
| `config.yml` | `debug`, stack visual max, card scale, interpolation ticks, table Y offset |
| `messages.yml` | Player-facing chat strings |
| `cards.yml` | Card catalog and named sets (`french_54`, `french_52`). |
| `games.yml` | Per-game rules, layout, blackjack min/max / auto-dealer defaults. Live auto/mint/shuffle live on the table ([GUILD_TABLES.md](GUILD_TABLES.md)) |
| `games.yml` | Per-game rules, layout, blackjack min/max / auto-dealer defaults, [hand card limits](#hand-card-limits). Live auto/mint/shuffle live on the table ([GUILD_TABLES.md](GUILD_TABLES.md)) |
| `help.yml` | The rule books `/games help` opens, one section per book, pages written by hand |
| `Data/tables/` | Gson for placed tables |

### Hand card limits

`hand-card-limit` under a game in `games.yml` caps how many cards one player can hold at that game's tables. The count includes cards still being dealt and every Blackjack split group. The bundled file sets 2 for `poker` and 5 for `draw`; `blackjack` and `freeplay` omit it. An omitted, zero or negative value leaves the hand unrestricted. Games copies `games.yml` only when it is missing, so an existing server must add the key to its own file.

ItemsAdder pack lives in the repo at `games/ItemsAdder/tfmc_games/`. Namespace: `tfmc_games`.

## Source layout
Expand Down Expand Up @@ -97,7 +101,8 @@ Ace file and IA id is `_1` or `1`, not 14. Ace-high ranking is a poker flag, not
| `/games help [game]` | `games.help` (default true) | Opens a rule book from `help.yml`. No game id opens the index |
| `/games reload` | `games.admin.reload` | Reload configuration |
| `/games place` | `games.admin` | Place a table without a deck item |
| `/games bet ...` | `games.bet` | Blackjack betting |
| `/games bet ...` | `games.bet` | Blackjack betting; `check`, `call`, `fold`, `raise` and `allin` for poker |
| `/games poker ...` | `games.bet` | Poker [tournament](HOLDEM.md#tournaments) settings and actions |

## Dependencies

Expand Down
8 changes: 8 additions & 0 deletions projects/Games/docs/TEST_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Run the checklist for the source and dependency versions being released. Player-

Run these checks on Minecraft **1.21.10** with the intended plugin dependencies and JVM from the [shared platform baseline](../../../PLATFORM.md). Record the source revision, server build, JVM and results; the checklist alone is not evidence of a passing release.

## Automated tests

`mvn clean verify` runs the JUnit suite (MockBukkit and Mockito) and writes JaCoCo reports to `target/site/jacoco/`. JaCoCo measures every production class with no exclusions; open `target/site/jacoco/index.html` to inspect uncovered behaviour. Coverage data is replaced on each run, so use the full suite when assessing repository-wide coverage.

Game scenarios drive public callbacks through complete Poker, Draw and Blackjack rounds across the real table, deck and money implementations, and assert game rules, money conservation or player-visible effects. Tests should protect supported behaviour, not create impossible internal states merely to execute a branch. Where no real caller can reach a branch, remove the branch rather than force it.

Packet tests verify ProtocolLib requests through mocked boundaries only. Packet encoding and client rendering are covered by the manual checks below.

---

## Build and startup
Expand Down