feat(render): #86 @ClearColor — Render phase auto-clears + auto-presents
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 23s
ci / build-and-test (push) Successful in 2m18s
commit-lint / conventional-commits (push) Successful in 4s
docs / build-and-deploy (push) Successful in 28s

@ClearColor(0xRRGGBB) declares the framebuffer clear colour, so the engine
owns the per-frame clear and flip: the Render phase clears to the colour at
the top and presents after the handlers run. Games drop the repeated
Screen.clear(color)/Screen.show() boilerplate, and the colour is configured
declaratively (an annotation) rather than in the handler body. Opt-in and
backward-compatible: a program with no @ClearColor is byte-for-byte identical
(it clears/presents itself, or the light system owns the present).

Parser reads @ClearColor(int) into g_clear_color/g_has_clear_color;
emit_game_main emits rt_clear before and rt_present after the Render phase,
gated on the flag. Example clear_color (pixel-readback verified — an undrawn
pixel holds the clear colour, proving the engine cleared), docs page +
inventory entry. Full suite 108/0, goldens byte-identical, fixpoint holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-02 07:10:44 +03:00
parent bccd26fb29
commit d9287d6b1d
8 changed files with 18108 additions and 17936 deletions

View file

@ -0,0 +1,25 @@
# clear_color.ludic — @ClearColor (#86): the Render phase auto-clears to a
# declaratively-configured colour at the top and auto-presents after the handlers
# run, so the game's Render handler carries NO Screen.clear / Screen.show. Verified
# by pixel readback after the frame loop: an undrawn pixel holds the clear colour
# (proving the engine cleared), and the drawn box is present.
#
# Driven headless by one stdin key ('q' quits after the frame renders).
# printf 'q' | bin/ludic examples/library/clear_color.ludic -> 1 1
program ClearColorDemo {
property Tag { n: int = 0 }
model P { Tag }
function bi(b: bool) -> int { if b { return 1 }; return 0 }
# No Screen.clear, no Screen.show — the engine clears to @ClearColor and presents.
@ClearColor(0x102030)
handler Draw phase Render {
Screen.fill_rectangle(10, 10, 4, 4, 0xffffff)
}
@OnQuit handler Report {
print(bi(Screen.pixel(200, 200) == 0x102030)) # 1 — background is the clear colour
print(bi(Screen.pixel(11, 11) == 0xffffff)) # 1 — the drawn box is there
}
}