Archetype.schema() now reports flat level-data field names.
Archetype.schema() now reports exported field names.
Project.schema() now reports exported field names separately from
level-data fields.
Project schemas and engine compilation now reject distinct archetypes with the same runtime name in one mode.
Union type expressions using | now accept None and existing unions as operands, and None can be used as a
Record field type or generic type argument.
Builtin constants, tuples, ranges, dictionaries, and sets now fall back to reflected operators when appropriate.
Compile-time binary operators and augmented assignment now follow reflected dispatch and grant priority only to
real strict subclasses, including inherited classmethod operators; builtin type aliases support unions in either
order.
Membership now supports iterable values that do not define __contains__.
Ordinary missing-attribute lookup now traces __getattr__ across direct access, getattr, hasattr, and class
patterns.
Standalone comparisons now preserve record-valued results from custom comparison methods.
Boolean conditions now use Python truthiness for supported compile-time constants.
The compiled range builtin now supports type, isinstance, issubclass, and union expressions.
Compiled dict.get(key) now supports an omitted default for a compile-time constant key.
Compiled range.index now accepts one positional argument.
Added tuple .index() support with optional positional-only bounds.
Fixed evaluation order for decorators and default arguments of nested functions.
Fixed Array construction and copying with records containing Final fields.
Fixed falsy archetype level-data values being replaced with zeros.
Fixed one-shot archetype iterables producing engines without archetypes.
Fixed match captures being visible before their pattern completely matches.
Fixed compile-time state accumulating across dev server rebuilds.
Invalid class patterns and invalid generator returns now report their offending source locations.
Compiled expressions, decorators, and default arguments now stop evaluating later subexpressions after an
earlier subexpression terminates.
Lambdas and generator expressions now treat assignment and comprehension targets as local throughout their
bodies.
Generator closures now track bindings read through nested callbacks across resumptions.
Generators now advance correctly when runtime control flow skips a yield and remain exhausted after completion.
Added runtime checks for reusing a generator through multiple iterator consumers.
for, generator expressions, and yield from no longer trace impossible exhaustion paths for iterators that
always yield a value.
Generator expressions that cannot yield or advance now terminate when runtime checks are enabled.
Fixed loop merging rejecting bindings that source code did not read.
Duplicate expanded-keyword errors now identify a lambda as <lambda>.
yield from now requires an iterator's next() method to return Maybe.
Fixed lambdas defined inside yield or yield from expressions failing to compile.
Fixed generator expressions over runtime iterables with compile-time false filters failing to compile.
Fixed generator expressions failing when an unrelated enclosing binding shares a name with a generator binding.
Fixed generator expression outermost iterables being evaluated in the wrong scope.
Fixed multiple functions or lambdas on one source line compiling the same body.
Compiled functions now reject global and nonlocal statements.
Fixed direct use of a result from a function that terminates on every path.
Assignment expressions inside generator expressions are now rejected.
A class or asyncdef statement in code skipped at compile time no longer affects the function containing
it.
Getter-only property assignments now report the property and target type consistently.
Corrected the documented input restrictions for compiled dict() and set() construction.
Membership now truth-tests custom __contains__ results, including compile-time constants.
Boolean contexts now bind classmethod and staticmethod implementations of __bool__ and __len__
correctly.
Implicit operations now ignore special methods synthesized by __getattr__.
Compilation errors now identify the property getter or __getattr__ that raised AttributeError during an
attribute lookup.
Unsupported matrix multiplication now reports the operator error.
Expanded keyword arguments now consistently reject invalid mappings and keys; duplicate keywords identify the
callee.
Class patterns now report excess positional subpatterns with the class and supported limit.
Class patterns now reject a non-tuple __match_args__ and non-string entries.
ArrayLike.index and tuple index now require integer-valued
bounds; tuple bounds are positional-only.
Compiled membership now rejects NotImplemented from __contains__.
A subclass attribute explicitly set to None now masks an inherited descriptor during compiled lookup.
Compiled range() arguments, enumerate() starting indices, and round() digit counts must now be
integer-valued.
Compiled len(), truth testing through __len__, and min() or max() now reject invalid __len__ results.
StreamGroup membership now treats fractional indices as absent.
Fixed strict-subclass right-operand dispatch in binary operations, comparisons, augmented assignment, and
dict or set membership.
Dict unpacking now reports that it is unsupported.
Dict equality comparison now reports that it is unsupported.
range() now rejects a zero step.
Fixed max() and min() failing to compile when given an explicit key=None together with two or more
arguments.
Fixed an augmented assignment such as interval&=other failing to compile when the type's corresponding
binary operator branches on a runtime value.
Corrected the published signatures of reversed, dict, max, min, range, random.randrange, super,
and the math module functions to match the calls they accept.
range item assignment now reports that it is unsupported.
Invalid unpacking assignments now report counted unpacking errors.
Fixed archetype mixins skipping __init_subclass__; unrecognized class keywords are now rejected.
Invalid unpacking assignments now identify the value type.
Builtin call errors now identify the builtin and supplied argument count.
Unexpected-keyword errors now identify the keyword and callee.
Unexpected-keyword errors for spawn() now name the archetype.
range.index() now rejects values outside the range.
random.randrange, random.randint, and random.choice now reject invalid ranges and inputs.
Sprite z-index tuples now require one to four entries, and pnpoly now requires a
nonempty polygon.
Fixed augmented assignment not using a reflected operator when applicable.
Hand-written in-place operators may now return a new object.
Calls now reject duplicate keyword arguments.
Item access and membership errors now use consistent Python-style wording.
Explicitly empty archetype names and imported or exported field names are now preserved.
Class-shaped global declarations now treat ClassVar members as class constants rather than stored fields.
Explicitly empty engine and level titles are now preserved.
Tutorial instruction APIs now reject use outside tutorial mode.
Building level data now rejects adding the same entity instance more than once.
Added support for localized text in options, buckets, and instructions, given as an
AnyText dict mapping locale codes to text.
Added support for issubclass. Both isinstance and issubclass now also accept a tuple of types.
Added support for math.degrees and math.radians.
Added support for map and filter over tuples, dicts, sets, and enum classes, behaving like the equivalent
generator expression. iter remains unsupported for these, which have no iterator, but now reports why.
enumerate, zip, min, and max now accept a set.
Fixed the else clause of a for loop being skipped when iterating over a tuple, dict, set, or enum class.
Fixed generator expression if filters being ignored when iterating over a tuple, dict, set, or enum class.
Fixed a name bound by a match capture pattern, or by a nested def, not being carried between loop iterations.
Fixed a dict subject incorrectly matching a sequence pattern such as case[a,b], and an internal error when
matching a sequence pattern against an enum class subject.
Fixed an internal error when using an empty sequence pattern (case[]).
A star sub-pattern in a sequence pattern, such as case[a,*rest], is now rejected when the case is visited.
Fixed the message expression of an assert being evaluated even when the assertion passed. An assert also now
converts its test the same way if does, so a value with __bool__ or __len__ behaves alike in both.
Fixed an internal error when using a bare variable annotation (x:int); it is now a no-op. As in Python, it
also makes the name local, so reading it before it is assigned is an error rather than reading a global.
A Record field annotated with a generic type missing its type arguments, such as
EntityRef rather than EntityRef[Any], is now rejected when the class is
defined.
An Array element type that is not a concrete supported type, such as Array
without its own type arguments, is now rejected when the array type is parameterized. Equivalent spellings of the
element type, such as int|float, Final[int], and Annotated[int,...], are now normalized so that they
share a single parameterization.
An Array size that is negative or not an integer is now rejected.
Fixed a @streams data field annotated with a plain type such as int being silently dropped.
@streams now reports the offending field name in every declaration error, and
correctly distinguishes a field annotated with Annotated[...] from one with a real default value.
The declaration decorators (@options, @skin,
@buckets, @streams, ...) now reject a base class other than object.
round's second parameter is now named ndigits, matching Python, so round(x,ndigits=2) works.
Fixed callable always returning False.
Fixed bool failing on runtime values, and on values whose __bool__ returns a Num. bool of an empty string
or None now correctly returns False.
Fixed reversed() failing to compile for values whose length is not a compile time constant.
sum now reports an error for non-numeric values instead of modifying the value passed as start.
min and max now honor the default argument for Array, VarArray,
and range.
map and filter now report a non-iterable argument the same way iter and zip do.
Fixed isinstance reporting a set or dict as a Record; issubclass rejects those pairings in the same way.
Fixed a numeric value returned by next on a generator changing when next was called again.
Fixed an overflow error when raising a float to a large power.
Fixed a copied EntityRef losing the entity it refers to, which wrote a dangling reference into level data. This
affected copy(), including copying an Array or Record that holds references,
and constructing an Array directly from references, such as Array(a.ref(),b.ref()).
Fixed != on an EntityRef created by ref() comparing fields rather than the referenced entity, so that two
references to different entities reported neither equal nor unequal while building level data.
Fixed the optimizer removing a block whose only contents were side effects.
Access to a dict with a non-compile-time-constant key is now supported when all values are compile time constants
of a single supported type (numeric, array, or record).
Usage of set literals containing non-numeric types is now supported.