Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arch/items/magic_tools/power_crystal/power_crystal.arc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ face power_crystal.101
animation power_crystal
is_animated 1
anim_speed 5
glow_radius 1
light_color fff0c0
type 156
weight 300
value 30000
Expand Down
7 changes: 7 additions & 0 deletions docs/LIGHT_SOURCE_AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,10 @@ Optional Classic renderer inspection may inform that decision, but its captures
are not merge or release prerequisites and must not enter content Git status.
The ledger and audit never change archetypes, maps, light behavior, or packaged
runtime content.

The base `power_crystal` and its six artifact variants inherit one radius-1
`fff0c0` source. Charge capacity, artifact upgrades, and multiple instances do
not alter that per-object radius or color. The deterministic Classic lifecycle
checks for ground, inventory, containment, trade, stronger-light precedence,
map transitions, logout/login, and death are recorded in
[`POWER_CRYSTAL_LIGHT_REVIEW.md`](POWER_CRYSTAL_LIGHT_REVIEW.md).
72 changes: 72 additions & 0 deletions docs/POWER_CRYSTAL_LIGHT_REVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Power-crystal light lifecycle review

Issue #95 was exercised against these immutable authored/runtime inputs:

- content authored commit: `2f786326601deaab4e21edb3ea86d68240add097`;
- Classic client/server commit: `7ad4acc27c222db7ce3e74d7db5ac93e9464cd28`;
- resources commit: `266ac693e5567e1c253384bff1d490f1e37fedca`;
- wrapper profile: `issue-95-power-crystal-runtime`;
- topology: `issue-95-power-crystal`;
- scenario: `issue-95-power-crystal`;
- state: `scenario-issue-95-power-crystal`.

The review-only `tools/light-source-review/dark-lab` map was staged only in the
isolated topology. The scenario account was provisioned by the wrapper; no
credential or mutable scenario state is part of this record.

## Deterministic assertions

Each row below records the decisive Classic Python-console operation and the
assertion that completed without `AssertionError` or traceback in the server
log. Object names use the `issue95v_` prefix so the run can remove stale test
objects before every sequence.

| Lifecycle state | Operation and asserted result |
| --- | --- |
| Clean control | Remove all named review objects; assert `activator.glow_radius == 0`. |
| Ground | Create `power_crystal` on the map; assert object radius `1`, color `0xfff0c0`, and carrier radius `0`. |
| Pickup | Insert the ground crystal directly into the player; assert carrier radius `1` and color `0xfff0c0`. |
| Drop | Insert the crystal back into the map; assert carrier radius `0` and object radius `1`. |
| Direct inventory | Create `power_crystal` directly in the player; assert radius `1` and color `0xfff0c0`. |
| Nested container | Move the direct crystal into a carried `sack`; assert carrier radius `0`; move it back directly and assert radius `1`. |
| NPC inventory | Create a stationary `woman` with a contained crystal; assert both player and NPC aggregate radii remain `0`. |
| Trade | Move the NPC crystal directly to the player; assert player radius `1`. |
| Shop stock | Mark the directly carried crystal unpaid and retain radius `1`; move unpaid stock into the merchant NPC and assert both aggregate radii are `0`. |
| Multiple and upgraded crystals | Carry the base crystal with `mana_crystal_100`; assert the aggregate remains radius `1`; destroy the upgrade and assert it remains radius `1`. |
| Stronger equipped light | Apply a radius-3 `torch` while carrying a crystal; assert radius `3` and `0xffc080`; add `mana_crystal_100` and retain the torch result; destroy the torch and assert fallback to radius `1` and `0xfff0c0`. |
| Map transition | Teleport with the direct crystal from the lab to Marigold at `(22,10)` and back; after each transfer assert the object exists and carrier radius is `1`. |
| Logout/login | Save the direct crystal, cleanly stop the topology, restart the same profile/scenario/state, and log in again; assert the object exists with radius `1` and color `0xfff0c0`. |
| Death/respawn | With the saved direct crystal and test-GM mode disabled, assert radius `1`, set HP to `-1`, and allow the Classic player process to execute death/respawn; assert the restored inventory object, radius `1`, and `0xfff0c0`. Nesting it immediately afterward produced radius `0`, proving no stale source; returning it directly restored radius `1`. Test-GM mode was restored and the state saved. |

The successful carrier/NPC/trade/upgrade/transition sequence is recorded from
`2026-08-11T09:59:49Z` through `10:00:44Z`. Clean logout occurred at
`10:03:44Z`; the same character logged in at `10:06:02Z`, and relogin
assertions completed at `10:06:28Z` and `10:06:30Z`. Death/respawn and the
post-death stale-source checks completed from `10:07:28Z` through `10:07:42Z`.
The independent ground/pickup/drop/torch-precedence sequence completed from
`10:12:56Z` through `10:13:14Z`.

The pinned Classic checkout also built `atrinik-server-tests` from commit
`7ad4acc27c222db7ce3e74d7db5ac93e9464cd28`. The focused command

```sh
ctest --test-dir /workspaces/atrinik/workspace/build/profiles/issue-95-power-crystal-runtime-eca840d37182/build/integrated \
-R '^server-unit-types\.light_apply$' --output-on-failure
```

passed all 14 `types.light_apply` cases, including stable strongest-light
selection, non-amplifying equal-radius inventory lights, removal/reinsertion,
map transfer/reload, and save/load reconstruction.

## Semantic and field preservation

The semantic review ledger binds the base `power_crystal`, each of its six
artifact variants, and the visible Marigold world instance to their effective
source digests. Rendered review images are generated output and are not kept in
the authored content repository.

The authored diff adds only `glow_radius 1` and `light_color fff0c0` to the
base archetype. The lossless validator and semantic inventory confirm that
charge capacity, mana value, artifact identity, quest upgrade fields,
merchant stock, rarity, value, weight, face, animation, and the remaining
gameplay fields are unchanged.
51 changes: 45 additions & 6 deletions maps/light-source-review.json
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,11 @@
"rationale": "obstacle_volcano_6 uses the lava and open fire palette entry to match its visible art.",
"semantic_sha256": "12cbd80e3e3dfd8aee50317270b57d5be49cda4591ab3cd46136356e441e1aea"
},
"power_crystal": {
"uncolored_disposition": "neutral",
"rationale": "power_crystal uses a restrained radius-1 holy gold-white light matching its animated luminous-white facets.",
"semantic_sha256": "b97dcc49d1dd9b1b9b9b6fac0e5ac62af78d80c2d6346b8fc6c6dff44204937f"
},
"pool_acid": {
"uncolored_disposition": "neutral",
"rationale": "pool_acid uses the established pink palette entry to match its saturated magenta liquid.",
Expand Down Expand Up @@ -606,11 +611,41 @@
"rationale": "The activated crystal artifact uses explicit soft-white light matching its pale animation.",
"semantic_sha256": "8b8ef22d27b78491c8d592e776ff3aa5b4768d84bf7f88379db8e8c3ecbc9ccf"
},
"gandyld_crystal_1": {
"uncolored_disposition": "neutral",
"rationale": "Gandyld's first mana-crystal upgrade inherits the base crystal's single restrained light without amplification.",
"semantic_sha256": "22948502e177c31818e6c6ff6adf313ec2ec638d163b73baa54a8382b7562b35"
},
"gandyld_crystal_2": {
"uncolored_disposition": "neutral",
"rationale": "Gandyld's second mana-crystal upgrade inherits the base crystal's single restrained light without amplification.",
"semantic_sha256": "32a4fc426e23b8cc07ccdcd75a8fe4a80862eb9019a3a68c6c1576276e73fe5a"
},
"gandyld_crystal_3": {
"uncolored_disposition": "neutral",
"rationale": "Gandyld's final mana-crystal upgrade inherits the base crystal's single restrained light without amplification.",
"semantic_sha256": "1eac2ded5df4886a9bd4c78e776c84893091b29db40702ac86ea319b0876e62c"
},
"halloween_abyss_jackolantern": {
"uncolored_disposition": "neutral",
"rationale": "The activated abyss jack-o-lantern uses explicit orange light matching its carved flame art.",
"semantic_sha256": "12e4f3ebcf546586c987d62b1046c9e7da42d91b861d74da0ca89e737e708532"
},
"mana_crystal_100": {
"uncolored_disposition": "neutral",
"rationale": "The 100-sp mana crystal inherits the base crystal's single restrained light independently of charge capacity.",
"semantic_sha256": "313c6244c28fda1c320e078bde969ae30483b29f0a6971f1b6d970555dec4d40"
},
"mana_crystal_25": {
"uncolored_disposition": "neutral",
"rationale": "The 25-sp mana crystal inherits the base crystal's single restrained light independently of charge capacity.",
"semantic_sha256": "ad059e2ed66de693c9f2e5c5867f2634fcb6d3b29f24dd206592208fd5f490ec"
},
"mana_crystal_50": {
"uncolored_disposition": "neutral",
"rationale": "The 50-sp mana crystal inherits the base crystal's single restrained light independently of charge capacity.",
"semantic_sha256": "b7ad18070369b68f7d1ea97f8f05b5099f42b1d12f782924ce2e1b208319479f"
},
"shield_holy_light": {
"uncolored_disposition": "neutral",
"rationale": "shield_holy_light uses the holy gold-white palette entry to match its authored description and art.",
Expand Down Expand Up @@ -1066,6 +1101,10 @@
"rationale": "The authored ff60c0 tint matches the visible art for plant_mushroom3.",
"semantic_sha256": "6ceb1c1fb74ce544f3af3c2953d8b490c1ac1e0daa5500bbe4fd1d1f8d91de39"
},
"power_crystal": {
"rationale": "The authored fff0c0 tint gives the luminous-white power-crystal art a restrained holy gold-white cast.",
"semantic_sha256": "bea61ff9366ac356e18058996fa0b978bbe5f5555fda73667f18510b08e2b75f"
},
"pool_acid": {
"rationale": "The authored ff60c0 tint matches pool_acid's saturated magenta liquid.",
"semantic_sha256": "e4c807e3f3ec2386dcdead66bc0a640b6eaf951c51d02f739a31c1970fcf09e2"
Expand Down Expand Up @@ -1207,7 +1246,7 @@
},
"context_checks": {
"overlap": {
"rationale": "Compared overlapping red, purple, and cold-blue crystal pools in Brynknot Abyss in both renderers, plus the unchanged Bone Cairn control.",
"rationale": "Compared overlapping red, purple, and cold-blue crystal pools in Brynknot Abyss in both renderers, plus the unchanged Bone Cairn control. The Marigold radius-1 power crystal sits beside stronger neutral helper lights and a currently non-emitting crystal ball without stacked focal color.",
"status": "pass"
},
"linked-depth": {
Expand Down Expand Up @@ -2371,7 +2410,7 @@
"rationale": "Rendered Temple of Zechna in paired smooth and discrete issue-102 views; overlapping crystal-owned red and purple pools preserve combat silhouettes, doors, and traversable floor edges.",
"visible_neutral": {},
"art_overrides": {},
"semantic_sha256": "7da9bc79d8bae7d3778ba05e9af3324874112569f983b0e28824ccc762babffa"
"semantic_sha256": "e54ef2e93051c857918508a7dc392eab220428374ed9622f4b4ebac5a7b95083"
},
"maps/shattered_islands/strakewood_island/zechna_temple/zechna_temple_1_1": {
"uncolored_disposition": "neutral",
Expand Down Expand Up @@ -3227,10 +3266,10 @@
},
"maps/shattered_islands/world_17_2_4": {
"uncolored_disposition": "neutral",
"rationale": "Rendered Wizards' Tower: Marigold in the lyondale_archipelago batch; neutral map-local fill preserves the outdoor ambient hierarchy while explicit emitters carry the scene's art cues.",
"rationale": "Rendered Wizards' Tower: Marigold with its radius-1 pale-gold power-crystal focus beside the currently non-emitting crystal ball; the stronger neutral helper lights retain the room hierarchy without stacked focal color.",
"visible_neutral": {},
"art_overrides": {},
"semantic_sha256": "a3e6bbd1ff143c1ea8ed687167a72f4a867d46a3b578fee190753abdec4c0c67"
"semantic_sha256": "2122d13accbe02dbaecc1445f98416b7a92c54301423f5b5b2b925e9dda492dd"
},
"maps/shattered_islands/world_17_2_5": {
"uncolored_disposition": "neutral",
Expand Down Expand Up @@ -4094,7 +4133,7 @@
"rationale": "Rendered Asteria in the strakewood_island batch; neutral map-local fill preserves the outdoor ambient hierarchy while explicit emitters carry the scene's art cues.",
"visible_neutral": {},
"art_overrides": {},
"semantic_sha256": "6ae04c7907a3ebb3c4c27ffa067490c0c3829a446d536cfba9621e49e0f00d4d"
"semantic_sha256": "b624147d29e798fb862489ca67d58cfe55d0d451c227b91745a0ff280aef90e9"
},
"maps/shattered_islands/world_4_48": {
"uncolored_disposition": "neutral",
Expand Down Expand Up @@ -4937,7 +4976,7 @@
"rationale": "Rendered Strakewood Island in the strakewood_island batch; neutral map-local fill preserves the outdoor ambient hierarchy while explicit emitters carry the scene's art cues.",
"visible_neutral": {},
"art_overrides": {},
"semantic_sha256": "05044f1d152d1dca3bc2edc04913557a95521a47c2cccf1ad2d0a68a85e8b916"
"semantic_sha256": "345978b2c19945137f7f3f2bdb5414db4565043fc434d2204f9fedcf9601f1cc"
},
"maps/shattered_islands/world_6_66_-1": {
"uncolored_disposition": "neutral",
Expand Down