Skip to content

Add pattern format v1 with 128x128 canvas support - #4972

Open
Nebualaxy wants to merge 8 commits into
openfrontio:mainfrom
Nebualaxy:feature/pattern-format-v1
Open

Add pattern format v1 with 128x128 canvas support#4972
Nebualaxy wants to merge 8 commits into
openfrontio:mainfrom
Nebualaxy:feature/pattern-format-v1

Conversation

@Nebualaxy

@Nebualaxy Nebualaxy commented Aug 12, 2026

Copy link
Copy Markdown

Before opening a PR: discuss new features on Discord first, and file bugs or small improvements as issues. You must be assigned to an approved issue — unsolicited PRs will be auto-closed.

Add approved & assigned issue number here:#4957

Resolves #4957

Description:

Adds a v1 pattern format so artist canvases can be square rather than capped at 129×65. v0 decoding is unchanged, so every existing cosmetic decodes exactly the same.

Describe the PR.
The v0 header packs scale(3) | width_lo(5) and width_hi(2) | height(6) into two bytes with nothing spare — width gets 7 bits, height only 6, purely because 16 bits doesn't divide evenly. There's no mask to widen. v1 uses a 4-byte header with 9 bits each for width and height and 3 bits reserved.

Bug fixed on the way. WebGLFrameBuilder reserves a 1024-byte row per player, but a maximum-size v0 pattern (129×65) needs 1049. .set() doesn't throw on overflow — it writes 25 bytes into the next player's row. It has never fired because no pattern has been that large, but it's live in main today. Related: slice(3) hardcoded the v0 header size, so any longer header would have misaligned every pixel.

Silent truncation fixed. v0 length checking is a minimum, so a pattern one pixel over the height limit wrapped and rendered wrong rather than erroring. v1 requires an exact payload length.

Hardening. Raising the schema cap would have let a v0 pattern carry ~8KB of trailing data through to Privilege.ts, since v0 length checking is lenient. v0 now rejects payloads over 1049 bytes — every currently-valid v0 pattern is well under the old 1403-character cap, so nothing that works today can fail this.

Sizing. MAX_PATTERN_DIMENSION is a single constant; the schema's max length, the CPU buffer, and the GPU texture width all derive from it, so they can't drift from the format again. Set to 128 → a 2048-byte row: 16MB across CPU buffer and GPU texture, against 8MB today. The v1 header can express up to 513, so raising the ceiling later is one line and needs no format change. 176 is the largest dimension that keeps the texture width inside the 4096 MAX_TEXTURE_SIZE that capped devices report.

No shader change — territory.frag.glsl already reads dimensions from patternMeta.

This makes the game able to read larger patterns. The pattern maker still needs to emit v1 headers before artists can author at that size, so nothing changes visibly on merge.
Screenshot 2026-08-11 180242
Screenshot 2026-08-11 180504
Screenshot 2026-08-11 180657
Screenshot 2026-08-11 181428
Screenshot 2026-08-11 181611
Screenshot 2026-08-11 182112

Please complete the following:

  • [☑️ ] I have added screenshots for all UI updates
  • [☑️ ] I process any text displayed to the user through translateText() and I've added it to the en.json file
    No user facing text added
  • [☑️ ] I have added relevant tests to the test directory

Please put your Discord username so you can be contacted if a bug or regression is found:

DISCORD_USERNAME

Nebualaxy

@Nebualaxy
Nebualaxy requested a review from a team as a code owner August 12, 2026 11:57
@CLAassistant

CLAassistant commented Aug 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added the auto-closed-needs-issue PR closed by gate — see comment for next steps label Aug 12, 2026
@github-actions

Copy link
Copy Markdown

Hi @Nebualaxy, thanks for the contribution.

This PR was automatically closed because it doesn't fit our contribution workflow:

  • You aren't currently assigned to an issue labelled approved, and
  • The change is larger than 50 lines (our cap for unsolicited contributions).

To contribute to OpenFront:

  1. For bugs or small quality-of-life improvements: open an issue. A maintainer will label it approved if it's something we'll work on.
  2. For feature ideas: discuss in the dev Discord first. We don't accept unsolicited feature PRs — even if they're good ideas, every merged feature is a permanent maintenance burden.
  3. Once an issue is labelled approved, comment asking to be assigned. After you're assigned, you can open a PR referencing that issue.

If you believe this was closed in error, please reach out on our Discord or comment below.

See CONTRIBUTING.md for the full contribution process.

Automated PR gate. Source.

@github-actions github-actions Bot closed this Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7e5f2bfc-cc93-4766-a52f-fdddedaf11de

📥 Commits

Reviewing files that changed from the base of the PR and between b535ca9 and ef0e185.

📒 Files selected for processing (1)
  • src/core/CosmeticSchemas.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/CosmeticSchemas.ts

Walkthrough

Pattern decoding now supports v0 and v1 formats with shared size limits and header-aware payload handling. WebGL frame storage and renderer texture operations use the shared row capacity. Tests cover validation, dimensions, scaling, offsets, and tiling.

Changes

Pattern format and rendering

Layer / File(s) Summary
Versioned decoding and validation
src/core/PatternDecoder.ts, src/core/CosmeticSchemas.ts, tests/PatternDecoder.test.ts
The decoder supports v0 and v1 headers, validates dimensions and payload lengths, returns headerBytes, and applies shared data limits. Tests cover decoding, validation, scaling, offsets, and tiling.
Bounded frame pattern storage
src/client/WebGLFrameBuilder.ts
Frame construction skips the format-specific header and copies only payloads within PATTERN_ROW_BYTES.
Shared renderer texture sizing
src/client/render/gl/Renderer.ts
Pattern texture allocation, initialization, and updates use PATTERN_ROW_BYTES instead of a fixed width.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PatternData
  participant PatternDecoder
  participant WebGLFrameBuilder
  participant Renderer
  PatternData->>PatternDecoder: decodePatternData
  PatternDecoder-->>WebGLFrameBuilder: dimensions, bytes, headerBytes
  WebGLFrameBuilder->>Renderer: bounded pattern row
  Renderer->>Renderer: upload pattern texture row
Loading

Possibly related PRs

Poem

Two headers pass the decoder gate,
Payload bounds define their state.
Shared rows keep texture data aligned,
Tests check every pixel stride.
v0 and v1 now share the line.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding pattern format v1 with 128×128 canvas support.
Description check ✅ Passed The description explains the v1 format, compatibility requirements, validation fixes, buffer sizing, and linked issue.
Linked Issues check ✅ Passed The changes satisfy issue #4957 by adding v1 decoding, preserving v0 behavior, validating payloads, and aligning shared size limits.
Out of Scope Changes check ✅ Passed The changed source files and tests directly support the linked issue objectives, with no unrelated code changes identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@iiamlewis iiamlewis removed the auto-closed-needs-issue PR closed by gate — see comment for next steps label Aug 12, 2026
@iiamlewis iiamlewis added the approved Approved for a PR, if you assigned to the issue. label Aug 12, 2026
@iiamlewis iiamlewis added this to the v34 milestone Aug 12, 2026
@iiamlewis iiamlewis reopened this Aug 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/PatternDecoder.ts`:
- Around line 34-47: Replace the Math.ceil-based calculations for
MAX_PATTERN_BYTES, MAX_PATTERN_DATA_LENGTH, and PATTERN_ROW_BYTES with
integer-only arithmetic or fixed integer constants, preserving the existing
rounded-up byte and base64url limits. Keep the exported constants and their
current values unchanged while removing floating-point operations from this
PatternDecoder limit calculation.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 85728c98-4c3a-4a5f-b4f2-2a345499d04e

📥 Commits

Reviewing files that changed from the base of the PR and between 8e1d2fd and 74038bb.

📒 Files selected for processing (5)
  • src/client/WebGLFrameBuilder.ts
  • src/client/render/gl/Renderer.ts
  • src/core/CosmeticSchemas.ts
  • src/core/PatternDecoder.ts
  • tests/PatternDecoder.test.ts

Comment thread src/core/PatternDecoder.ts Outdated
@github-actions github-actions Bot added the auto-closed-needs-issue PR closed by gate — see comment for next steps label Aug 12, 2026
@github-actions

Copy link
Copy Markdown

Hi @Nebualaxy, thanks for the contribution.

This PR was automatically closed because it doesn't fit our contribution workflow:

  • You aren't currently assigned to an issue labelled approved, and
  • The change is larger than 50 lines (our cap for unsolicited contributions).

To contribute to OpenFront:

  1. For bugs or small quality-of-life improvements: open an issue. A maintainer will label it approved if it's something we'll work on.
  2. For feature ideas: discuss in the dev Discord first. We don't accept unsolicited feature PRs — even if they're good ideas, every merged feature is a permanent maintenance burden.
  3. Once an issue is labelled approved, comment asking to be assigned. After you're assigned, you can open a PR referencing that issue.

If you believe this was closed in error, please reach out on our Discord or comment below.

See CONTRIBUTING.md for the full contribution process.

Automated PR gate. Source.

@github-actions github-actions Bot closed this Aug 12, 2026
@github-project-automation github-project-automation Bot moved this from Development to Complete in OpenFront Release Management Aug 12, 2026
@github-project-automation github-project-automation Bot moved this from Complete to Development in OpenFront Release Management Aug 12, 2026
@github-project-automation github-project-automation Bot moved this from Development to Triage in OpenFront Release Management Aug 12, 2026
@Nebualaxy

Copy link
Copy Markdown
Author

Removed floating point calculations

@iiamlewis iiamlewis reopened this Aug 12, 2026
@iiamlewis iiamlewis added keep-open Exempt from auto-close and removed auto-closed-needs-issue PR closed by gate — see comment for next steps labels Aug 12, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 12, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Approved for a PR, if you assigned to the issue. keep-open Exempt from auto-close

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

Increase limits for max pattern size to allow for more detailed submissions

3 participants