# BYOND DM parity research baseline

Research date: 2026-10-26. Target reference: official BYOND 516 documentation.
Current release verification: BYOND 516.1688, confirmed in the official 516 release notes.

## What the official reference contains

The official DM reference is broader than a list of global procedures. It covers:

- DM syntax, operators, preprocessor directives, macros, text entities, and special values.
- The type tree: `/area`, `/atom`, `/client`, `/datum`, `/icon`, `/image`, `/list`, `/map`, `/mob`, `/obj`, `/proc`, `/savefile`, `/sound`, `/turf`, `/var`, `/verb`, and `/world`.
- Type variables and instance procedures, including mouse/input events, movement, appearance, rendering, HUDs, particles, filters, sounds, browser controls, savefiles, database objects, and networking.
- Client scripts, aliases, macros, skins, browser integration, HTML/CSS output, and security notes.
- 516 additions such as vectors, pixlocs, associative-only lists, `astype()`, `<=>`, `lerp()`, `load_ext()`, named animation/filter support, `icon_w`/`icon_z`, `SCREEN_*` positioning, linked sounds, and browser mouse/DPI values.
- 516.1650 behavior: `atom.pixloc` includes `bound_x`/`bound_y`, matching the southwest bound anchor.

## Measured Craft++ baseline

| Surface | Craft++ baseline | Interpretation |
|---|---:|---|
| F1 reference topics | 69 | Generated/data-driven guide topics |
| Registered callable built-ins | generated from `BuiltinProcs` | Runtime recognition surface |
| Official global-procedure audit | 100% registered | Registration is not equivalent to behavioral parity |
| Official reference sections | ~1,500 headings | Includes vars, types, UI, scripts, notes, and non-global APIs |

The global-procedure score must therefore not be used as the complete parity score. The next audit needs separate scores for syntax, global procs, type vars/procs, runtime behavior, resources, client/UI, and IDE/reference coverage.

## Phased route to extended parity

1. **Inventory and contracts:** generate a machine-readable inventory of official names and classify each as syntax, proc, var, type, flag, UI, or documentation.
2. **Runtime foundations:** appearance/filter/particle/sound objects, atom vars, client/world vars, and exact list/vector/pixloc semantics.
3. **Compiler and syntax:** DM path expressions, proc references, `caller`/`callee`, C-style pragma modes, macro edge cases, and compatibility warnings.
4. **Client and UI:** skin controls, `winset`/`winget`, browser/DM Script behavior, mouse coordinates, DPI, command aliases, and macros.
5. **Persistence and external APIs:** savefile, database, filesystem/resource, `call_ext`, and Byondapi-compatible adapters.
6. **Conformance:** one test per documented contract, generated API coverage reports, and an F1 topic for every completed family.

## Website and Hub account boundary

The Craft++ Hub implements a separate local identity and ownership system. Its public key profiles are only discoverable when the key owns at least one visible listing; hidden listings do not appear on profiles. It does not accept BYOND credentials, authenticate BYOND keys, or modify BYOND.com ownership. BYOND's publishing guide describes unique hub paths, private-by-default entries, version/download metadata, helper roles, and optional passwords to authenticate live game announcements; Craft++ still lacks the live-announcement service and BYOND account integration.

Research sources: [BYOND publishing guide](https://www.byond.com/developer/articles/publish) and [BYOND login page security notice](https://secure.byond.com/login.cgi?login=1%3Bnoscript%3D1%3Burl%3Dbyond%3A%2F%2F).

## Phase 39: `findtext()` case-insensitive byte offsets

The official [`copytext()` reference](https://www.byond.com/docs/ref/info.html) states that text positions are byte positions and specifically distinguishes byte indices from character indices for non-ASCII text. `findtext()` likewise reports the position in its input. Craft++ previously lowercased the full haystack and returned an index in the transformed UTF-8 data; case mappings that change encoded byte length (for example, `K` to `k`) shifted the reported position. The matcher now folds one Unicode scalar at a time and uses offsets from the original UTF-8 string. A regression test asserts that `findtext("Kx", "x")` returns 4 and that `findtext("K", "k")` remains case-insensitive.

## Phase 40: `text2ascii()` Unicode code points

The official [`text2ascii()` reference](https://www.byond.com/docs/ref/info.html) states that `pos` is a byte position, while the result is the character's ASCII or Unicode code. Craft++ previously returned the byte at that offset, so `text2ascii("é")` returned 195 (the first UTF-8 byte) instead of 233 (U+00E9). It now decodes the code point beginning at the requested UTF-8 byte position. The regression coverage expects 233 for `é` and keeps the ASCII byte-position case (`text2ascii("éx", 3) == 120`).

## Phase 41: `copytext()` end-position conversion

The official [`copytext()` reference](https://www.byond.com/docs/ref/info.html) defines `End` as the byte position immediately following the last character copied, with 1-based text positions. Craft++ previously used a positive `End` directly as a zero-based exclusive array offset, so `copytext("abc", 1, 3)` returned all three characters instead of `"ab"`. The conversion now subtracts one for positive end positions while retaining negative positions counted from the end and `End=0` as the full-string default. Tests cover exact positive and negative slices and BYOND's documented U+FFFD replacement for UTF-8 sequences cut at byte boundaries.

## Phase 42: `copytext_char()` negative character positions

The official [Unicode reference](https://www.byond.com/docs/ref/info.html) says `_char` text procs use character positions and that most text procedures allow negative positions counted backward from the end. Craft++ had treated a negative `copytext_char()` start as position zero and a negative end as the default end. It now converts negative start/end positions relative to the rune count before applying bounds. Regression cases cover `copytext_char("abcd", -2) == "cd"` and an end of `-1` excluding the last character.

## Sources

- Official [DM Reference](https://www.byond.com/docs/ref/info.html)
- Official [BYOND 516 release notes](https://www.byond.com/docs/notes/516.html)
- Official [BYOND stable download/version page](https://www.byond.com/games/download/)
- Official [Dream Maker guide](https://www.byond.com/docs/guide/guide.html)

