Crash-tan Crash-tan

CrashCore 1.15.0 Released!

Crash BASIC 1.15.0 Release Notes

written by Crash-tan

THE "STOP WALKING THROUGH WALLS THAT ARE ACTUALLY SPRITES" RELEASE

Sprites can now act as solid obstacles to other sprites. Previously, SOLID only worked against boundaries. If you wanted an NPC to block the player, you had to manually check SPRITECOLLISION every frame and handle the pushback yourself.

Now:

SET SPRITE playerSprite SOLID SPRITES("wall", "npc", "rock")

The behavior engine handles the pushback automatically during the physics tick, same as boundary collision. It's one-sided: the moving sprite stops, the tagged sprite stays put. Both sprites need to opt in — the moving sprite declares which tags to collide with, and the obstacle just needs a matching tag.

All the SOLID/GHOST forms

SET SPRITE n SOLID                           ' Boundaries only (unchanged)
SET SPRITE n SOLID SPRITES("king","walls")   ' Boundaries + sprite tags
SET SPRITE n SOLID SPRITES()                 ' Clear sprite tags, keep boundary solid
SET SPRITE n GHOST                           ' Clear everything (boundary + sprite)

Works in the full SET SPRITE form too:

SET SPRITE 1, 100, 200, "hero" SOLID SPRITES("wall")

Custom Bounding Boxes Now Actually Work

BBOX was being sent to the graphics frontend and then... ignored for collision purposes. The behavior engine was using raw texture dimensions for everything: boundary collision, SPRITECOLLISION(), SPRITETOUCHING$(), and boundary overlap detection.

Now BBOX(x1, y1, x2, y2) is stored on the sprite state and used consistently across all collision paths. If you have a 64x64 character sprite where only the bottom 32x32 should collide:

SET SPRITE player BBOX(0, 0.5, 1.0, 1.0)

This affects:

  • Boundary pushback (SOLID against boundaries)
  • Sprite-to-sprite pushback (SOLID SPRITES)
  • SPRITECOLLISION() — manual sprite overlap queries
  • SPRITETOUCHING$() / SPRITETOUCHINGX() / SPRITETOUCHINGY() — boundary edge detection
  • FOR COLLISIONS — boundary overlap detection for non-solid boundaries

SPRITETOUCHING$ works with SOLID SPRITES + supports "ANY"

SPRITETOUCHING$ now checks sprites registered via SOLID SPRITES(...) in addition to boundaries. If your player is pushed up against a king-tagged sprite, SPRITETOUCHING$(player, "LEFT", "king") returns "king".

Also added "ANY" as an edge — checks all four sides and returns the first match:

' Am I touching anything?
IF SPRITETOUCHING$(player, "ANY") <> "" THEN
    PRINT "Touching something!"
END IF

' Am I touching a specific sprite tag on any edge?
IF SPRITETOUCHING$(player, "ANY", "king") <> "" THEN
    PRINT "Next to the king!"
END IF

Also works with SPRITETOUCHINGX() and SPRITETOUCHINGY().

LOCATE RELATIVE

LOCATE RELATIVE deltaRow, deltaCol offsets the cursor from its current position instead of setting an absolute row/column. Handy for overwriting text in place:

PRINT "Score: 0";
LOCATE RELATIVE 0, -1
PRINT "5";

False yield starvation with CALL RENDER

Games using CALL RENDER would randomly crash with "program executed too many statements without yielding" even though the main loop had a YIELD. The render callback runs on the pattern tick thread but shares the same statement counter as the main thread — so render callback statements accumulated on the counter between main-thread yields, eventually crossing the 100k threshold. Render callbacks now reset the yield marker after each execution.

Also

  • 22 new unit tests covering SOLID SPRITES syntax (all forms), sprite-to-sprite collision resolution, tag filtering, one-sided pushback, bbox collision rect math, and bbox integration with SPRITECOLLISION.