Skip to content

Variable-size element table, and a fix for Spawn.DefensiveElement - #8

Open
Caeldeth wants to merge 2 commits into
mainfrom
feature/element-table-variable-size
Open

Caeldeth wants to merge 2 commits into
mainfrom
feature/element-table-variable-size

Conversation

@Caeldeth

Copy link
Copy Markdown
Contributor

Summary

This PR makes two changes. Neither change breaks existing data or code.

1. Spawn.DefensiveElement reads the wrong list (HXML-25)

Spawn.DefensiveElement counts Defense.Elements, but it reads Damage.Elements. The server uses this property in Monolith.cs to set the defensive element of a spawned monster. The results are:

  • A spawn with <Defense> and no <Damage> throws NullReferenceException.
  • A spawn with one defense element and no damage elements throws InvalidOperationException.
  • A spawn with different damage and defense lists gets the wrong defensive element.

Current content does not cause these errors. In world and ceridwen, each spawn has the same elements in <Damage> and <Defense>.

OffensiveElement and DefensiveElement now use one helper. The helper reads the list of the property. It returns None when the list is absent or empty.

2. Variable-size element table (HXML-24, part A)

ElementTable.xsd requires exactly 9 Source rows, each with exactly 9 Target entries. The element tables in world and ceridwen have 10 rows, because they include Undead. Both tables fail schema validation for this reason.

  • Source and Target accept 1 or more entries.
  • A new DefaultMultiplier attribute on <ElementTable> (default 1) applies to each pair that the table does not declare.
  • xs:unique rejects two Source rows with the same element. It also rejects two Target entries with the same element in one row.
  • A new method, ElementTable.GetMultiplier(source, target), returns the declared multiplier. It returns DefaultMultiplier if the row, the entry or the Multiplier attribute is missing.

The ElementType enum does not change in this PR. A later PR changes the element set.

Generated code

tools/regenerate.sh regenerates src/Objects/ElementTable.cs. The only change is the new DefaultMultiplier property (17 lines).

The regeneration ran on Windows. On Windows, the script writes a different header path and different line endings (HXML-26). These differences were removed, so the file is the same as the output of a Linux run.

Tests

  • 4 new tests for the spawn elements. 3 of them fail on main.
  • 10 new tests for the element table: schema validation and GetMultiplier. The test project now copies src/XSD/*.xsd to its output directory, so the tests validate against the schema that ships.
  • Full suite: 103 pass, 3 fail. The same 3 tests fail on main: LoadDataContainsExpectedData, LoadDataAsyncContainsExpectedData and GetTotal. They expect 176 variant items, but the current ceridwen data gives 621.
  • The world and ceridwen element tables pass validation against the new schema.

Not in this PR

  • The package version stays 1.0.0-alpha2.
  • The server still reads the element table with .First() and a fixed table name (HXML-7). After this PR is released, the server can use GetMultiplier.

Spawn.DefensiveElement counts Defense.Elements, but it reads
Damage.Elements. A spawn with <Defense> and no <Damage> throws an
exception. A spawn with different lists gets its defensive element
from the damage list.

OffensiveElement and DefensiveElement now use one helper. The helper
reads the list of the property. It returns None when the list is
absent or empty.
ElementTable.xsd requires exactly 9 Source rows, each with exactly 9
Target entries. The world and ceridwen tables have 10 rows, because
they include Undead. Both tables fail validation for this reason.

This change does these things:

- Source and Target accept 1 or more entries.
- A new DefaultMultiplier attribute (default 1) applies to each pair
  that the table does not declare.
- xs:unique rejects two Source rows with the same element. It also
  rejects two Target entries with the same element in one Source row.
- ElementTable.GetMultiplier(source, target) returns the declared
  multiplier. It returns DefaultMultiplier if the Source row, the
  Target entry or the Multiplier attribute is missing.

The test project copies the XSD files to its output directory. The
tests use these files to validate tables against the schema.

This branch had an error being deployed

1 failed deployment
deploy — 0af9eafe Deployed Oct 20, 2026 by Caeldeth via build (10.0.x) #118
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.

1 participant