94052573b3bd7eb6597bc3326ce54a99512b9ba5
Action Blocks
Online player-vs-player falling-block game with items.
Developer documentation: see doc/ for architecture, game rules, protocol, frontend, deployment and how-to guides.
| Component | Path | Tech |
|---|---|---|
| Game server (logic, lobbies, players) | actionBlocks_server/ |
ASP.NET Core 10, SignalR |
| Website | actionBlocks_website/ |
React 19 + Vite + TypeScript, CSS Modules, served by nginx |
Gameplay
- 10x20 field, hold, 5-piece preview, ghost piece, bag randomizer, wall kicks, 0.5 s lock delay (15 move resets).
- Garbage from line clears (attack table incl. spins, back-to-back, combos) goes to opponents in a round-robin cycle.
- 1 in 10 pieces carries an item inside one of its blocks. Clear the line containing that block to collect it (max 10, FIFO).
- 1-9 selects the item target (1 = you, 2.. = opponents in the order shown). F uses the first item on the target.
- You never see who targets you, but every opponent's items are shown beneath their mini field.
- Item names flash on top of the field they hit.
Controls: arrows or WASD to move/rotate/soft drop, Space for hard drop, Z/Q/Ctrl to rotate left, C/Shift to hold.
Local development
# server on :5080
cd actionBlocks_server && dotnet run --project src/ActionBlocks.Server --urls http://localhost:5080
dotnet test # game logic tests
# website on :5173, proxies /hub to the server
cd actionBlocks_website && npm install && npm run dev
Deployment
docker network create actionBlocks_website # if not already created
docker network create actionBlocks_server
docker compose up -d --build
The website uses relative URLs. It works under a sub-path such as /website/, whether or not the proxy strips that prefix.
The reverse proxy (attached to both networks) should route:
- the site to
actionblocks-website:80 /hubtoactionblocks-server:8080, with WebSocket upgrade headers forwarded
| Variable | Container | Purpose |
|---|---|---|
SERVER_URL |
website | Hub URL as seen by the browser. Empty means <site origin>/hub. Written into config.js at container start. |
ALLOWED_ORIGINS |
server | Comma-separated CORS origins. Empty allows any origin. |
HUB_PATH |
server | Hub endpoint path (default /hub). |
PATH_BASE |
server | Prefix to accept when the proxy forwards a sub-path unstripped, e.g. /server. |
Game__* |
server | Overrides any GameSettings value, e.g. Game__ItemSpawnChance=0.2. |
Extending
Adding an item
- Create a class implementing
IIteminactionBlocks_server/src/ActionBlocks.Game/Items/. - Register it in
ItemRegistry.Default. - Add an entry with the same id to
itemVisualsinactionBlocks_website/src/theme/assets.ts, and add an icon inpublic/assets/items/.
Changing rules
- Values:
GameSettings. - Behaviour behind interfaces:
IRotationSystem,IRandomizer,IGarbageCalculator,IScoreCalculator,IGarbageTargeter. - The match flow lives in
Match, and the per-player simulation inPlayerGame.
Changing graphics
- Every image path is in
src/theme/assets.ts. You can set an image logo there withuiAssets.logo. - Block colors are in
src/theme/colors.ts. - Block drawing style is in
src/render/draw.ts. - Key bindings are in
src/config/keybindings.ts.
Languages
C#
47.7%
TypeScript
44.9%
CSS
6%
Dockerfile
0.6%
HTML
0.5%
Other
0.3%