Skip to content

Tutorial: build an arena minigame - #25

Merged
PyXiion merged 4 commits into
masterfrom
claude/arena-tutorial
Sep 28, 2026
Merged

PyXiion merged 4 commits into
masterfrom
claude/arena-tutorial

Conversation

@PyXiion

@PyXiion PyXiion commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Stacked on #24: the tutorial uses the new event model. Once #24 is merged, this PR's base becomes master.

Tutorial

A nine-chapter tutorial on the site (/tutorial). It grows one script, config/ignis/arena.lua, into a PvP arena where the last player standing wins:

  1. Commands and saved settings: register, permissions, mc.data, and the "assigning a table stores a copy" rule.
  2. The arena region: regions and block protection with cancellable events and priority.
  3. Rounds: a game loop with phases, mc.scheduleRepeating, and a celebration with async.sleep.
  4. Fights: knockouts via a cancelled entity.death, and region enter/leave handlers.
  5. Boss bar and scoreboard.
  6. Statistics and leaderboard: player.data, a leaderboard in mc.data, a hologram.
  7. Kits and inventories: the player's items are stashed via serialise, and kits are picked from a chestgui menu.
  8. Events for other scripts: mc.emit("arena:win") plus a separate rewards script (diamonds, a Discord webhook via async.fetch).
  9. Reloads and crashes: what a reload keeps and removes, uninit, returning items after a crash, debugging.

Each chapter ends with the complete file at that point (site/tutorial/arena/NN-*.lua, embedded via ?raw).

Checks (site/tutorial/test.sh, new tutorial CI job)

  • Every line of the code snippets on the pages must appear in that chapter's checkpoint file.
  • Every checkpoint file is checked with lua-language-server --check against lua-types/ (Lua 5.2, including hints).
  • The game logic runs in lua5.2 against a fake API (test/mock.lua):
    • a smoke test for every chapter;
    • a full scenario on the final version: setup, kits, rounds, knockouts, leaving the region and the server, a stranger entering, reload, a restart with a JSON round trip, crash recovery, and the rewards script.

The tutorial has not been run on a real server. Only the mock and LuaLS verify it.

Bugs found along the way

  • lua-types
    • mc.on/region:on overloads listed several events as a union. LuaLS only matched the first one, so e was untyped in player.join, player.leave, tick, entity.death, block.place and others. There is now one overload per event.
    • The chestgui types described methods that don't exist.
    • mc.createItem(id, opts) was missing.
    • Fixed a syntax error in registerBehaviour.
  • Script permissions
    • register(..., perm) and player:hasPermission called Permissions.check without a default level. That returns false when no permissions mod answers, so on a server without one, nobody (not even operators) could run a script command that has a permission.
    • They now fall back to op level 4, like /ignis.
  • whitelist example: it assigned an empty local table to mc.data and then changed the local one, so entries were not saved until a reload. The storage reference now explains the copy semantics.

🤖 Generated with Claude Code

https://claude.ai/code/session_01X7gxWF7FdViJa9dKAZJiac


Generated by Claude Code

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@PyXiion
PyXiion added this pull request to stack #27 September 28, 2026 12:22
Base automatically changed from claude/sleepy-bardeen-br7spn to master September 28, 2026 12:23
- mc.on / region:on overloads listed several event names in one union;
  LuaLS matched only the first, so e was untyped in player.join,
  player.leave, tick, entity.death, block.place and others. One
  overload per name now.
- chestgui: describe the real API (set/button/decorate/open/close)
  instead of setItem/onClick, which the library does not have.
- mc.createItem: add the (id, opts) form used by demo.lua.
- Fix a syntax error in mc.registerBehaviour, drop vec operators LuaLS
  does not support, move SimpleLib.defaultOverlay under its class.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7gxWF7FdViJa9dKAZJiac
register(syntax, fn, permission) and player:hasPermission used
Permissions.check without a default level, which is false when no
permissions mod answers. On a server without one, nobody (operators
included) could run a script command that has a permission. Fall back
to op level 4, like /ignis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7gxWF7FdViJa9dKAZJiac
Assigning a table to mc.data/player.data stores a copy. The whitelist
example assigned an empty local table and kept changing the local one,
so entries added before the next reload were never saved. Explain the
rule in the storage reference and note how permissions behave without a
permissions mod.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7gxWF7FdViJa9dKAZJiac
A step-by-step tutorial that grows one script, config/ignis/arena.lua,
into a PvP arena: setup commands and mc.data, a region with block
protection, a game loop with phases, knockouts via entity.death, boss
bar and sidebar, statistics and a leaderboard hologram, kits with a
chestgui menu and stashed inventories, an arena:win event with a
rewards script, and cleanup on reload.

Each chapter ends with the complete file (site/tutorial/arena/NN-*.lua,
embedded in the page). site/tutorial/test.sh checks that the snippets
in the pages match those files, runs lua-language-server against
lua-types on them, and plays the game through a fake API in Lua 5.2;
a new CI job runs it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7gxWF7FdViJa9dKAZJiac
@PyXiion
PyXiion force-pushed the claude/arena-tutorial branch from 4c61aef to f7381de Compare September 28, 2026 12:23
@PyXiion
PyXiion merged commit 01ba6d2 into master Sep 28, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants