Skip to content
zigchoPublic

About

an osu server in zig, built for stable and lazer

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

zigcho

anticheat

Stable and lazer replay submissions feed the private detector. lazer uploads are decoded as full replay files and checked against the resolved beatmap; custom mod settings stay out of behavioural rules the current detector cannot model. the staff anticheat panel keeps the two score sources separate.

new native uploads also need their compressed solo-score metadata. its statistics, maximum statistics, mods and settings must agree with the upload, as must any stored pauses, rank and unmodded total. older trailers can lack those newer fields; absence is not a contradictory claim. changing the replay version does not skip the core checks. this catches inconsistent score claims; it is not full replay re-scoring or proof that a matching play is clean. old saved replays remain downloadable.

player exclusions now have two explicit effects: hide review keeps collecting evidence, while skip checks bypasses anticheat analysis for that player until the record expires or is revoked. old exclusions remain review-only. every change needs an administrator, a reason and an expiry; auth and score-token validation are never bypassed.

anticheat_enforce_integrity=true rejects malformed passed replays and verifiable score-integrity failures before they affect stats or boards. it does not turn behavioural suspicions into automatic bans. the staff panel shows whether that switch is actually on and whether the private module loaded.

an osu! server written in Zig. i wanted one server i could actually understand, change and run properly without treating the production work as somebody else's problem.

release 1 is the point where Stable, zigcho!lazer and the website became one thing. they use the same local account, user id, moderation state, presence and shared player stats. none of it uses an official osu! account. their scoreboards stay separate where the clients genuinely score differently.

what is here

  • Stable login, chat, friends, spectating, multiplayer, tournaments and ScoreV2
  • vanilla, Relax and Autopilot scores, stats, PP, replays, pins and weighted top plays
  • zigcho!lazer profiles, maps, leaderboards, achievements, chat, spectating, Quick Play, rooms and ranked duels
  • a proper website for profiles, beatmaps, scores, replays, teams, multiplayer and account settings
  • the kai bot, player commands, staff controls, BN map ranking and moderation tools
  • PostgreSQL, private object storage, beatmap mirroring, backups, restore drills and rollback releases

combined stats use lazer's legacy score value and keep the highest-PP play for each map. Stable and lazer plays still have their own views, because pretending their raw score values are interchangeable would be wrong.

the full release 1 notes are in updates/2026-08-24-lazer-multiplayer-profiles-and-routes.md. newer changelogs are read from the raw GitHub files, so an update does not need a client rebuild just to change the words.

build

the replay counter also builds our PP bridge for the browser. install that Rust target once with rustup target add wasm32-unknown-unknown; the release runner already does it.

zigcho is pinned to Zig 0.16.0. the PP bridge also needs Rust, SQLite 3 and PostgreSQL with libpq.

zig build test
zig build test -Doptimize=ReleaseSafe
zig build -Doptimize=ReleaseSafe
ZIGCHO_POSTGRES_URL='host=/var/run/postgresql dbname=zigcho user=zigcho connect_timeout=5' \
  ./zig-out/bin/zigcho 127.0.0.1 8080

the server build is PostgreSQL by default. SQLite is only kept for fixtures and offline tools; build those explicitly with zig build -Dpostgres=false. copy config.example.ini to config.ini for local secrets. the real config is ignored. the useful player-path checks live in tools/, including Stable web/map checks and lazer solo, multiplayer and spectator runs.

release backups need rclone 1.60+, curl 7.75+ and GNU timeout on the host. the helper reads the existing storage config, uploads in bounded parts and checks a full ranged download against the original SHA-256 before activation. game uploads still use Zigcho's own object API.

the old SQLite importers and PostgreSQL migration utility are optional: zig build legacy-tools. normal server releases do not package them. if you need a runner-built copy, enable include_legacy_tools when starting the release workflow. zig build test-changelog checks the changelog without building the PP bridge or server.

production binaries come from the pinned Linux GitHub runner, not my Mac. each release lives at /opt/zigcho/releases/<commit> and is activated through tools/activate-release.sh, which backs up and restore-tests PostgreSQL before switching the live symlink. the separate zigcho!lazer repo builds the portable Windows, macOS, Linux, Android and unsigned iOS clients.

layout

runtime timings are documented in src/telemetry/README.md. /metrics/runtime is the local-only scrape that stays independent of database queries; /metrics also includes the database and cache totals.

the history follow-up fixes the measured history deadlocks and cold rank-update join. the short 100- and 1,000-player workloads now pass, with their failures, missed work and different runner CPUs recorded. longer capacity testing is deferred; these short runs are not a sustained-capacity claim. the earlier query comparison keeps the original results.

  • src/main.zig — the small server entrypoint
  • src/server/ — app state, HTTP routing, Stable and lazer routes, IRC, workers and command-line jobs
  • src/postgres_store.zig — the storage compatibility facade
  • src/storage/postgres/ — PostgreSQL accounts, maps, scores, chat, multiplayer and moderation repositories
  • src/storage/contracts.zig — shared storage types and validation, without either database backend
  • src/storage/sqlite/ — the same domains for legacy fixtures and offline tools; src/storage.zig keeps their existing entry points
  • src/lazer_multiplayer/ — rooms, ranked play, archives, score handling, transport and wire formats, with the existing tests beside each domain
  • the rest of src/ — shared protocols, scoring, sessions and the website
  • database/ — schemas and ordered migrations
  • pp/ — the local PP bridge
  • deploy/ and tools/ — production and acceptance work
  • updates/ — the release history

protocol work is checked against the official osu! client, the Bancho documentation and the MIT-licensed Akatsuki bancho.py implementation. the separate Stable conformance harness inventories the whole legacy surface and can replay the same stateful transcript against both servers.

licence

the code uses the Zigcho Public Use License. public servers, production use, modifications and free redistribution are allowed. keep the credit, link back here, mark what you changed and do not sell it, charge for access or pretend the work is entirely yours. the private anticheat has its own permission-only licence and is not included in this grant. older copies already released under MIT keep their existing MIT terms.

this is unofficial. osu! belongs to ppy Pty Ltd; zigcho is not affiliated with or endorsed by them.

About

an osu server in zig, built for stable and lazer

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages