From 4bf51998dc93ed2b4c21cc7a448f1017f9b2ebce Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sat, 23 May 2026 22:24:27 +0100 Subject: [PATCH] implements PLN-0085 --- discussion/index.ndjson | 2 +- ...rgba8888-tests-fixtures-and-conformance.md | 16 +++---- .../repositories/PackerAssetWalker.java | 5 +-- .../PackerRuntimeAssetMaterializerTest.java | 3 +- .../FileSystemPackerWorkspaceServiceTest.java | 44 +++++++------------ .../PackerAssetDeclarationParserTest.java | 11 ++--- .../PackerAssetDetailsServiceTest.java | 10 ++--- 7 files changed, 35 insertions(+), 56 deletions(-) diff --git a/discussion/index.ndjson b/discussion/index.ndjson index f696db9c..c26c309f 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,5 +1,5 @@ {"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":38,"PLN":87,"LSN":53,"CLSN":1}} -{"type":"discussion","id":"DSC-0038","status":"open","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-05-23","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0081","file":"PLN-0081-rgba8888-packer-and-studio-spec-propagation.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0082","file":"PLN-0082-rgba8888-palette-model-and-argb-conversion.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0083","file":"PLN-0083-rgba8888-glyph-payload-emission-and-sizes.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0084","file":"PLN-0084-rgba8888-packer-projections-and-workspace-apis.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0085","file":"PLN-0085-rgba8888-tests-fixtures-and-conformance.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0086","file":"PLN-0086-rgba8888-final-integration-and-residue-removal.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0038","status":"open","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-05-23","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0081","file":"PLN-0081-rgba8888-packer-and-studio-spec-propagation.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0082","file":"PLN-0082-rgba8888-palette-model-and-argb-conversion.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0083","file":"PLN-0083-rgba8888-glyph-payload-emission-and-sizes.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0084","file":"PLN-0084-rgba8888-packer-projections-and-workspace-apis.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0085","file":"PLN-0085-rgba8888-tests-fixtures-and-conformance.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0086","file":"PLN-0086-rgba8888-final-integration-and-residue-removal.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]}],"lessons":[]} {"type":"discussion","id":"DSC-0037","status":"done","ticket":"pbs-autocomplete-parameter-names","title":"PBS autocomplete parameter names for stdlib and method calls","created_at":"2026-05-08","updated_at":"2026-05-14","tags":["compiler-pbs","studio","lsp","autocomplete","signature-help","stdlib"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0037-pbs-autocomplete-parameter-names/LSN-0052-canonical-callable-parameter-names-through-pbs-editor-assistance.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14"}]} {"type":"discussion","id":"DSC-0036","status":"open","ticket":"pbs-symbol-documentation-and-hover-markdown","title":"Modelo de documentacao de simbolos em PBS e consumo markdown no hover","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["compiler","compiler-pbs","studio","lsp","vscode","editor","hover","documentation","markdown"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-pbs-symbol-documentation-and-hover-markdown.md","status":"open","created_at":"2026-05-08","updated_at":"2026-05-08"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0035","status":"done","ticket":"pbs-lsp-editor-assistance-wave-1","title":"Wave 1 de assistencia editorial via LSP para PBS no VS Code","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["studio","lsp","vscode","compiler","compiler-pbs","editor","completion","hover","signature-help"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0051","file":"discussion/lessons/DSC-0035-pbs-lsp-editor-assistance-wave-1/LSN-0051-compiler-backed-editor-assistance-for-pbs.md","status":"done","created_at":"2026-05-08","updated_at":"2026-05-08"}]} diff --git a/discussion/workflow/plans/PLN-0085-rgba8888-tests-fixtures-and-conformance.md b/discussion/workflow/plans/PLN-0085-rgba8888-tests-fixtures-and-conformance.md index 7c31a622..f0c14c6a 100644 --- a/discussion/workflow/plans/PLN-0085-rgba8888-tests-fixtures-and-conformance.md +++ b/discussion/workflow/plans/PLN-0085-rgba8888-tests-fixtures-and-conformance.md @@ -2,9 +2,9 @@ id: PLN-0085 ticket: studio-packer-rgba8888-asset-pipeline title: RGBA8888 Tests, Fixtures, and Conformance Updates -status: review +status: done created: 2026-05-23 -completed: +completed: 2026-05-23 ref_decisions: - DEC-0037 tags: @@ -123,12 +123,12 @@ RGB565 glyph palette payload expectations. ## Acceptance Criteria -- [ ] Tests use `rgba8888` as canonical palette data. -- [ ] Tests assert RGBA channel order and alpha preservation. -- [ ] Tests assert 16 usable palette entries. -- [ ] Tests assert magenta is ordinary or no longer special. -- [ ] Tests assert 4096-byte palette blocks where payload size is checked. -- [ ] Packer test fixtures no longer rely on `convertedRgb565`. +- [x] Tests use `rgba8888` as canonical palette data. +- [x] Tests assert RGBA channel order and alpha preservation. +- [x] Tests assert 16 usable palette entries. +- [x] Tests assert magenta is ordinary or no longer special. +- [x] Tests assert 4096-byte palette blocks where payload size is checked. +- [x] Packer test fixtures no longer rely on `convertedRgb565`. ## Dependencies diff --git a/prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java b/prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java index 95c2a95d..0213aa2e 100644 --- a/prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java +++ b/prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java @@ -349,10 +349,7 @@ public class PackerAssetWalker { for (byte value : tile.paletteIndices()) { maxUsedIndex = Math.max(maxUsedIndex, Byte.toUnsignedInt(value)); } - if (maxUsedIndex == 0) { - continue; - } - final int requiredColorCount = maxUsedIndex; + final int requiredColorCount = maxUsedIndex + 1; final Optional fragilePalette = declaredPalettes.stream() .filter(palette -> palette.colorCount() < requiredColorCount) .findFirst(); diff --git a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java index fa6b6123..abbf1ba4 100644 --- a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java +++ b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java @@ -250,8 +250,7 @@ final class PackerRuntimeAssetMaterializerTest { private static Map palettePipeline() { final var payload = MAPPER.createObjectNode(); - payload.putArray("originalArgb8888").add(0xFFFF0000); - payload.putArray("convertedRgb565").add(0xF800); + payload.putArray("rgba8888").add(0xFF0000FF); final var declaration = MAPPER.createObjectNode(); declaration.put("index", 0); declaration.set("palette", payload); diff --git a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java index 72000040..ee184c61 100644 --- a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java +++ b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java @@ -295,9 +295,7 @@ final class FileSystemPackerWorkspaceServiceTest { final ObjectNode palette = palettes.addObject(); palette.put("index", 0); palette.putObject("palette") - .putArray("originalArgb8888").add(0xFFFF0000); - ((ObjectNode) palette.path("palette")) - .putArray("convertedRgb565").add(0xF800); + .putArray("rgba8888").add(0xFF0000FF); final var artifacts = manifest.putArray("artifacts"); artifacts.addObject().put("file", "confirm.png").put("index", 0); MAPPER.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest); @@ -330,8 +328,10 @@ final class FileSystemPackerWorkspaceServiceTest { final int packedPixelBytes = (assetTable.get(0).path("metadata").path("width").asInt() * assetTable.get(0).path("metadata").path("height").asInt()) / 2; final int paletteStart = payloadOffset + assetOffset + packedPixelBytes; - assertEquals(0xF81F, readLeUnsignedShort(assetsPa, paletteStart)); - assertEquals(0xF800, readLeUnsignedShort(assetsPa, paletteStart + 2)); + assertEquals(0xFF, assetsPa[paletteStart] & 0xFF); + assertEquals(0x00, assetsPa[paletteStart + 1] & 0xFF); + assertEquals(0x00, assetsPa[paletteStart + 2] & 0xFF); + assertEquals(0xFF, assetsPa[paletteStart + 3] & 0xFF); assertEquals(1, assetTable.get(0).path("asset_id").asInt()); assertEquals("GLYPH", assetTable.get(0).path("bank_type").asText()); assertEquals("NONE", assetTable.get(0).path("codec").asText()); @@ -369,9 +369,7 @@ final class FileSystemPackerWorkspaceServiceTest { final ObjectNode palette = palettes.addObject(); palette.put("index", 0); palette.putObject("palette") - .putArray("originalArgb8888").add(0xFF00FF00).add(0xFFFF0000); - ((ObjectNode) palette.path("palette")) - .putArray("convertedRgb565").add(0x07E0).add(0xF800); + .putArray("rgba8888").add(0x00FF00FF).add(0xFF0000FF); final var artifacts = manifest.putArray("artifacts"); artifacts.addObject() .put("artifact_id", "art-confirm") @@ -417,7 +415,7 @@ final class FileSystemPackerWorkspaceServiceTest { final int payloadOffset = (int) readLeLong(assetsPa, 12); final var assetTable = MAPPER.readTree(projectRoot.resolve("build/asset_table.json").toFile()); final int assetOffset = assetTable.get(0).path("offset").asInt(); - assertEquals(0x21, assetsPa[payloadOffset + assetOffset] & 0xFF); + assertEquals(0x10, assetsPa[payloadOffset + assetOffset] & 0xFF); } @Test @@ -436,9 +434,7 @@ final class FileSystemPackerWorkspaceServiceTest { final ObjectNode palette = palettes.addObject(); palette.put("index", 0); palette.putObject("palette") - .putArray("originalArgb8888").add(0xFFFF0000); - ((ObjectNode) palette.path("palette")) - .putArray("convertedRgb565").add(0xF800); + .putArray("rgba8888").add(0xFF0000FF); final var artifacts = manifest.putArray("artifacts"); artifacts.addObject().put("file", "selected.png").put("index", 0); MAPPER.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest); @@ -502,9 +498,7 @@ final class FileSystemPackerWorkspaceServiceTest { final ObjectNode palette = palettes.addObject(); palette.put("index", 0); palette.putObject("palette") - .putArray("originalArgb8888").add(0xFFFF0000); - ((ObjectNode) palette.path("palette")) - .putArray("convertedRgb565").add(0xF800); + .putArray("rgba8888").add(0xFF0000FF); final var artifacts = manifest.putArray("artifacts"); artifacts.addObject().put("file", "oversized.png").put("index", 0); MAPPER.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest); @@ -533,9 +527,7 @@ final class FileSystemPackerWorkspaceServiceTest { final ObjectNode palette = palettes.addObject(); palette.put("index", 0); palette.putObject("palette") - .putArray("originalArgb8888").add(0xFFFF0000); - ((ObjectNode) palette.path("palette")) - .putArray("convertedRgb565").add(0xF800); + .putArray("rgba8888").add(0xFF0000FF); final var artifacts = manifest.putArray("artifacts"); artifacts.addObject().put("file", "checker.png").put("index", 0); MAPPER.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest); @@ -1016,8 +1008,7 @@ final class FileSystemPackerWorkspaceServiceTest { project(projectRoot), AssetReference.forAssetId(1), List.of(Map.of( - "originalArgb8888", List.of(0xFFFF0000), - "convertedRgb565", List.of(0xF800))))).success()); + "rgba8888", List.of(0xFF0000FF))))).success()); final var manifest = MAPPER.readTree(assetRoot.resolve("asset.json").toFile()); final var selectedArtifact = manifest.path("artifacts").get(0); @@ -1074,8 +1065,7 @@ final class FileSystemPackerWorkspaceServiceTest { project(projectRoot), AssetReference.forAssetId(1), List.of(Map.of( - "originalArgb8888", List.of(0xFFFF0000), - "convertedRgb565", List.of(0xF800))))).success()); + "rgba8888", List.of(0xFF0000FF))))).success()); final var manifest = MAPPER.readTree(assetRoot.resolve("asset.json").toFile()); final var selectedArtifact = manifest.path("artifacts").get(0); @@ -1129,20 +1119,18 @@ final class FileSystemPackerWorkspaceServiceTest { AssetReference.forAssetId(1), List.of( Map.of( - "originalArgb8888", List.of(0xFFFF0000, 0xFF00FF00), - "convertedRgb565", List.of(0xF800, 0x07E0)), + "rgba8888", List.of(0xFF0000FF, 0x00FF00FF)), Map.of( - "originalArgb8888", List.of(0xFF0000FF), - "convertedRgb565", List.of(0x001F))))); + "rgba8888", List.of(0x0000FFFF))))); assertTrue(response.success()); final var manifest = MAPPER.readTree(projectRoot.resolve("assets/ui/atlas/asset.json").toFile()); assertEquals(2, manifest.path("output").path("pipeline").path("palettes").size()); assertEquals(0, manifest.path("output").path("pipeline").path("palettes").get(0).path("index").asInt()); - assertEquals(0xFFFF0000, manifest.path("output").path("pipeline").path("palettes").get(0).path("palette").path("originalArgb8888").get(0).asInt()); + assertEquals(0xFF0000FF, manifest.path("output").path("pipeline").path("palettes").get(0).path("palette").path("rgba8888").get(0).asInt()); assertEquals(1, manifest.path("output").path("pipeline").path("palettes").get(1).path("index").asInt()); - assertEquals(0x001F, manifest.path("output").path("pipeline").path("palettes").get(1).path("palette").path("convertedRgb565").get(0).asInt()); + assertEquals(0x0000FFFF, manifest.path("output").path("pipeline").path("palettes").get(1).path("palette").path("rgba8888").get(0).asInt()); } @Test diff --git a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java index a66c90ee..29654ec9 100644 --- a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java +++ b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java @@ -158,8 +158,7 @@ final class PackerAssetDeclarationParserTest { { "index": 1, "palette": { - "originalArgb8888": [4294901760], - "convertedRgb565": [63488] + "rgba8888": [-16776961] } } ] @@ -174,7 +173,7 @@ final class PackerAssetDeclarationParserTest { assertTrue(result.valid()); assertTrue(result.declaration().outputPipelineMetadata().get("palettes").isArray()); assertEquals(1, result.declaration().outputPipelineMetadata().get("palettes").get(0).path("index").asInt()); - assertEquals(63488, result.declaration().outputPipelineMetadata().get("palettes").get(0).path("palette").path("convertedRgb565").get(0).asInt()); + assertEquals(0xFF0000FF, result.declaration().outputPipelineMetadata().get("palettes").get(0).path("palette").path("rgba8888").get(0).asInt()); } @Test @@ -194,15 +193,13 @@ final class PackerAssetDeclarationParserTest { { "index": 0, "palette": { - "originalArgb8888": [4294901760], - "convertedRgb565": [63488] + "rgba8888": [-16776961] } }, { "index": 0, "palette": { - "originalArgb8888": [4278255360], - "convertedRgb565": [2016] + "rgba8888": [16711935] } } ] diff --git a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDetailsServiceTest.java b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDetailsServiceTest.java index 3c5c65f6..079fd9ed 100644 --- a/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDetailsServiceTest.java +++ b/prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDetailsServiceTest.java @@ -66,9 +66,7 @@ final class PackerAssetDetailsServiceTest { final ObjectNode declaration = palettes.addObject(); declaration.put("index", 3); declaration.putObject("palette") - .putArray("originalArgb8888").add(0xFFFF0000).add(0xFF00FF00); - ((ObjectNode) declaration.path("palette")) - .putArray("convertedRgb565").add(0xF800).add(0x07E0); + .putArray("rgba8888").add(0xFF0000FF).add(0x00FF00FF); mapper.writerWithDefaultPrettyPrinter().writeValue(manifestPath.toFile(), manifest); final PackerAssetDetailsService service = service(); @@ -77,8 +75,8 @@ final class PackerAssetDetailsServiceTest { assertEquals(1, result.details().pipelinePalettes().size()); assertEquals(3, result.details().pipelinePalettes().getFirst().get("index")); assertEquals( - List.of(0xFFFF0000, 0xFF00FF00), - result.details().pipelinePalettes().getFirst().get("originalArgb8888")); + List.of(0xFF0000FF, 0x00FF00FF), + result.details().pipelinePalettes().getFirst().get("rgba8888")); } @Test @@ -202,7 +200,7 @@ final class PackerAssetDetailsServiceTest { final var palette = (Map) selectedFile.metadata().get("palette"); assertEquals(16, ((Number) tile.get("width")).intValue()); assertEquals(16, ((Number) tile.get("height")).intValue()); - assertFalse(((List) palette.get("originalArgb8888")).isEmpty()); + assertFalse(((List) palette.get("rgba8888")).isEmpty()); } @Test