Add shared multiplayer gear puzzle (Chamber of Motion)
Players open a no-login link and see live cursors and dragged gear pieces synced in real time, backed by a small Workerman WebSocket relay (src/Command/PuzzleRelayCommand.php) run alongside symfony serve - no Docker/Mercure hub needed. The board renders the wall artwork with a spare-gears tray, and a "Reset puzzle" button (visible only to logged-in users, verified server-side via a signed token) lets the DM wipe the shared state for everyone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Puzzle\PuzzleResetTokenSigner;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
/**
|
||||
* Shared, no-login puzzle screens: everyone with the link sees the same
|
||||
* board, the same pieces, and each other's cursors, synced over the
|
||||
* WebSocket relay in {@see \App\Command\PuzzleRelayCommand}.
|
||||
*/
|
||||
final class PuzzleController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire(env: 'PUZZLE_RELAY_PUBLIC_URL')]
|
||||
private readonly string $relayPublicUrl,
|
||||
private readonly PuzzleResetTokenSigner $resetTokenSigner,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/puzzle/{room}', name: 'app_puzzle_room', requirements: ['room' => '[a-z0-9-]+'], methods: ['GET'])]
|
||||
public function room(string $room): Response
|
||||
{
|
||||
return $this->render('puzzle/room.html.twig', [
|
||||
'room' => $room,
|
||||
'relayPublicUrl' => $this->relayPublicUrl,
|
||||
// Only a logged-in user gets a token that lets them reset the shared
|
||||
// board; anonymous players can play but not wipe it for everyone.
|
||||
'resetToken' => $this->getUser() ? $this->resetTokenSigner->sign($room) : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user