added item probability

This commit is contained in:
2026-10-24 20:32:37 +02:00
parent 1996b9c83e
commit 471dc33f0e
132 changed files with 99 additions and 36 deletions
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+2 -1
View File
@@ -59,7 +59,8 @@ cp .env.example .env
| `ALLOWED_ORIGINS` | server | empty → any origin | Comma-separated list of origins allowed to connect, e.g. `https://game.example.com` |
| `PATH_BASE` | server | empty | Prefix to accept if the proxy forwards a sub-path **without stripping it**, e.g. `/server` |
| `HUB_PATH` | server | `/hub` | Hub endpoint path. It is fixed to `/hub` in the compose file |
| `Game__<Setting>` | server | see `GameSettings.cs` | Overrides gameplay values, e.g. `Game__ItemSpawnChance=0.2`. Add these under the server's `environment:` in the compose file |
| `ITEM_SPAWN_CHANCE` | server | `0.1` | Chance (0..1) that each block of a new piece carries an item. Passed to the server as `Game__ItemSpawnChance` |
| `Game__<Setting>` | server | see `GameSettings.cs` | Overrides other gameplay values, e.g. `Game__CountdownSeconds=5`. Add these under the server's `environment:` in the compose file |
Start or update:
Regular → Executable
View File
Regular → Executable
+2 -1
View File
@@ -95,11 +95,12 @@ All numbers are in `ActionBlocks.Game/GameSettings.cs`. There are two ways to ch
```yaml
actionblocks-server:
environment:
Game__ItemSpawnChance: "0.15"
Game__MaxInventory: "6"
Game__LockDelaySeconds: "0.6"
```
The item chance already has its own variable: set `ITEM_SPAWN_CHANCE` in `.env` (the compose file passes it as `Game__ItemSpawnChance`).
To add a **new** setting, add an `init` property with a default to `GameSettings` and read it where needed. Configuration binding picks it up automatically.
If you change the board width or height, the website adapts automatically, because `MatchState.width`/`height` drive the rendering.
Regular → Executable
View File
Regular → Executable
+1 -1
View File
@@ -114,7 +114,7 @@ A player is eliminated when any of these happens:
### Spawning and collecting
- Each **newly generated** piece has a 10% chance (`GameSettings.ItemSpawnChance`) to carry an item. The item sits in one random mino of the four. The roll happens when the piece enters the queue, so items are already visible in the preview and in hold (`Items/ItemRegistry.cs`, `ItemSpawner`).
- Each of the four minos of a **newly generated** piece has its own 10% chance (`GameSettings.ItemSpawnChance`, env `ITEM_SPAWN_CHANCE`) to carry an item, so one piece can carry several items (up to four). Each item is picked separately. The roll happens when the piece enters the queue, so items are already visible in the preview and in hold (`Items/ItemRegistry.cs`, `ItemSpawner`).
- When the piece locks, the item stays in that cell of the board. Item cells move with the board: they drop when lines below them clear, rise with garbage, and travel along when boards are swapped.
- **Clearing the row that contains the item cell** moves the item into the player's inventory.
- If the cell is destroyed another way (for example by *Clear Line* or *Wipe Out*), the item is lost.
Regular → Executable
+3 -4
View File
@@ -132,13 +132,12 @@ sequenceDiagram
"active": {
"type": 7,
"cells": [[4,-1],[3,0],[4,0],[5,0]],
"itemIndex": 2, // which of the 4 cells carries the item, -1 if none
"itemId": "swap"
"items": [null, null, "swap", null] // items[i] is the item in cells[i], null if none
},
"ghost": [[4,17],[3,18],[4,18],[5,18]],
"hold": { "type": 3, "itemId": null, "itemIndex": -1 },
"hold": { "type": 3, "items": [null, null, null, null] },
"holdUsed": false,
"next": [ { "type": 4, "itemId": null, "itemIndex": -1 }, … ],
"next": [ { "type": 4, "items": ["nuke", null, null, "blind"] }, … ],
"inventory": ["add_line", "blind"], // oldest first; inventory[0] is used by F
"score": 1250,
"lines": 12,
Regular → Executable
+2 -2
View File
@@ -50,7 +50,7 @@ actionBlocks_server/
```csharp
readonly record struct Cell(byte Color, string? ItemId = null) // Color 0 = empty, 1-7 pieces, 8 garbage
sealed record PieceSpec(PieceType Type, string? ItemId, int ItemMinoIndex) // what sits in the queue
sealed record PieceSpec(PieceType Type, IReadOnlyList<string?>? Items) // what sits in the queue; Items[i] = item in mino i
sealed record ActivePiece(PieceSpec Spec, int X, int Y, int Rotation) // a spec placed on the board
```
@@ -115,7 +115,7 @@ public sealed record ItemContext(PlayerGame User, PlayerGame Target, Random Rand
```
- `ItemRegistry.Default` lists all active items. `ItemRegistry.PickRandom` chooses an item weighted by `SpawnWeight`.
- `ItemSpawner.Decorate(type)` turns a raw piece type into a `PieceSpec`, sometimes with an item.
- `ItemSpawner.Decorate(type)` turns a raw piece type into a `PieceSpec`. Each mino rolls `ItemSpawnChance` on its own, so a piece can carry 0–4 items.
See [Extending → Add an item](extending.md#add-a-new-item).