Skip to content
dr4wnPublic

About

An original connection-puzzle game for Roblox: drag pipes between matching endpoints so every pair is joined and every cell is covered.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

Currents

An original connection-puzzle game for Roblox: drag pipes between matching endpoints so every pair is joined and every cell is covered. Built on the Knit framework with Rojo for version control, and ProfileStore for persistence.

Getting started

aftman install                     # installs rojo from aftman.toml
rojo build -o currents-game.rbxlx  # build the place
rojo serve                         # then connect the Rojo plugin in Studio

Studio play-testing uses ProfileStore's mock store automatically, so test sessions never touch live player data. For DataStore-backed features (leaderboards) in Studio, enable "Studio Access to API Services".

Development commands

lua tests/run.lua                          # headless domain test suite (30 tests)
lune run tests/boot.luau                   # full headless boot: server + client + UI + a 1v1 duel
python3 tools/generate_levels.py           # regenerate certified level packs
luac -p $(find src -name '*.lua')          # syntax lint (Luau-only files excluded)

tests/boot.luau runs the exact shipped code under a Roblox API shim (tests/rbxshim.luau) using Lune: it boots Knit server and client, builds every screen, clicks through the menus, solves a campaign level, a daily, and a time-trial session, and wins a full casual 1v1 duel. It needs /tmp/tree.json extracted from a fresh rojo build (see the script header).

Troubleshooting a broken boot

If the game shows nothing when you press Play:

  1. Delete any old currents-game.rbxlx, run rojo build -o currents-game.rbxlx again, and open the fresh file (or reconnect rojo serve). Stale place files carry old script copies.
  2. Check the Output window. A healthy boot prints [Currents] server started and [Currents] client started. Any line starting with [Currents] FATAL names the exact module that failed to load.
  3. Old prototype files (GridController, DuelController, DuelService, AStar, Hello.luau) are inert stubs and safe to delete outright.

Project structure

src/
  shared/
    Engine/           pure domain engine: PuzzleDef, Engine (path state
                      machine, undo/redo, win detection), Validator
    LevelPacks/       generated packs with certified solutions (52 campaign
                      levels 5x5..10x10, 30 daily pool, 24 arena pool)
    LevelData.lua     catalog, global ids, deterministic daily/arena selection
    Constants.lua     palette, symbols, UI theme, competitive tuning, tiers
  server/
    Services/         DataService (profiles), LevelService (validation, hints,
                      grading), DailyService (streaks), TimeTrialService,
                      MatchService (1v1 casual/ranked/private/tournament),
                      TeamMatchService (2v2 Team Set Race), TournamentService
                      (8-player single elim), RatingService (Glicko-1),
                      LeaderboardService, SocialService (block/report)
    Modules/          Glicko.lua
  client/
    Controllers/      Input, Settings, Audio, Board (engine <-> view <-> input),
                      UI (screen shell + navigation)
    UI/               Builder toolkit, BoardView renderer, 12 screens
tests/run.lua         headless engine/validator/property tests
tools/generate_levels.py   reverse-construction generator + certifying solver

What is implemented

  • Full standard rules: orthogonal paths, collision trimming, backtracking, foreign-endpoint blocking, exact win validation (connect all pairs AND fill every cell), server-side revalidation of every completion claim.
  • Free Play: 6 packs / 52 levels, per-level saves and resume, undo/redo, restart confirmation, full-path hints from certified solutions (marked in grading), star/check grades, best time/actions, achievements.
  • Daily puzzle with UTC date keys, streaks and longest-streak tracking.
  • Time Trial: size x duration variants, server-authoritative clock, seeded identical sequences, personal bests and leaderboard submission.
  • Competitive (spec section 31): ranked 1v1 best-of-three with expanding-window matchmaking, casual 1v1, private room codes, 2v2 Team Set Race with atomic puzzle claims and preset quick-messages, 8-player single-elimination tournaments with rating-seeded brackets and walkovers, Glicko-1 ratings with placements and named tiers, OrderedDataStore leaderboards, match history, disconnect grace/forfeit, surrender, block/report tools.
  • Accessibility: endpoint symbols per pair, high-contrast palette, reduced motion, keyboard play, restartable at any time, no flashing.

Honest limitations / deferred work

  • Multiplayer scope is per-server. Matchmaking queues, tournaments, and private rooms pair players inside one Roblox server instance. Cross-server play needs MemoryStore queues + TeleportService and a coordination backend.
  • Finish timing uses validated server receipt order, not the spec's full hash-chained action-log latency-envelope reconstruction. Anti-cheat is solution validation + minimum-solve-time + rate limits; a headless solver on a modified client cannot be fully prevented (as the spec itself notes).
  • Reconnect-to-match honors the grace window only within the same server; Roblox rejoin usually lands elsewhere, so it typically resolves as forfeit.
  • Bridges, blocked-cell shaped boards (engine supports the mask; no shipped content), sprint mode, spectating, seasons rollover automation, and monetization are not built.
  • Sounds are Roblox built-in placeholder clips; swap AudioController.SOUNDS for original assets before publishing. Haptics setting is a stored no-op (Roblox exposes no mobile haptics API).
  • Uniqueness is proved only where the solver confirmed it (small boards); larger boards state "any valid solution counts", per spec 3.6.

Regenerating content

tools/generate_levels.py builds boards by reverse construction (random Hamiltonian partition via backbite, minimum segment length 3), rejects low-quality boards, certifies solvability, counts solution uniqueness up to a node cap on boards <= 7x7, and emits the Lua packs with embedded solutions. The test suite re-validates every shipped solution against the engine validator on every run.

About

An original connection-puzzle game for Roblox: drag pipes between matching endpoints so every pair is joined and every cell is covered.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages