- runtime: HEADLESS_FRAME_PATH, STICK_DEADZONE / STICK_LEFT_X/Y, key and byte codes as char literals throughout (`k == 'w'`, `fill(rt_map, ' ', …)`) - ludic.gameplay/stats: drop the duplicate `stat_field` (it answered "atk" for every build stat); Stats.base uses stats_field_name - ludic.shooter: compare aim modes and fire patterns with AimMode.* and WeaponPattern.* instead of raw ints; STICK_RIGHT_X/Y - ludic.npcai: DecisionMade / brain_set_state use AiState.* - examples/games/menu.ludic uses Font.load / Ui.* with FONT_PATH and BACKDROP named; strings.ludic header says what it prints - whole tree: `x = x + 1` → `x += 1` (single-term right-hand sides only), `0 - x` → `-x`, ASCII codes → char literals; every .ludic and every ```ludic fence reformatted with the fixed formatter (whitespace only) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
57 lines
2.4 KiB
Text
57 lines
2.4 KiB
Text
# component_access.ludic — typed component access from an entity handle:
|
|
# `Prop.of(e)` reads and writes fields, `Prop.has(e)` is safe for -1 and dead
|
|
# handles, `Prop.count()` counts, `Prop.despawn_all()` clears; `countdown` fields
|
|
# tick toward 0 each Update; `Enum.Variant` typed vars and machines. Prints:
|
|
# 9 15 10 33 1 0 0 1 0 1 101 100 102 1 2 1 0
|
|
program ComponentAccess {
|
|
import "ludic.core/components.ludic"
|
|
property Hero { roll_frames: int = 0, iframes: int = 0, flash: countdown = 0 }
|
|
property Tag { n: int = 0 }
|
|
model Player { Position, Hero }
|
|
model Thing { Position, Tag }
|
|
enum HeroState { Idle, Rolling, Swinging }
|
|
var hero_state: HeroState = HeroState.Rolling
|
|
var player: int = -1
|
|
var frames: int = 0
|
|
function step() -> void {
|
|
machine hero_state {
|
|
state Idle { print(100); become Swinging }
|
|
state Rolling { print(101); become Idle }
|
|
state Swinging { print(102); become Rolling }
|
|
}
|
|
}
|
|
handler Tick phase Update {
|
|
frames += 1
|
|
if frames == 1 {
|
|
player = spawn Player { Position { x: 3, y: 4 }, Hero { roll_frames: 9, flash: 3 } }
|
|
spawn Thing { Position { x: 30, y: 40 }, Tag { n: 7 } }
|
|
print(Hero.of(player).roll_frames) # 9
|
|
Hero.of(player).iframes = 20
|
|
Hero.of(player).iframes -= 5
|
|
print(Hero.of(player).iframes) # 15
|
|
let hero = Hero.of(player)
|
|
hero.roll_frames += 1
|
|
print(Hero.of(player).roll_frames) # 10
|
|
print(Position.of(player).x + Position.of(1).x) # 33
|
|
print(Hero.has(player)) # 1
|
|
print(Hero.has(1)) # 0
|
|
print(Hero.has(-1)) # 0
|
|
print(Tag.has(1)) # 1
|
|
despawn 1
|
|
print(Tag.has(1)) # 0
|
|
print(Position.count()) # 1: the player
|
|
spawn Thing { Position { x: 1 } }
|
|
}
|
|
if frames == 2 {
|
|
step(); step(); step() # 101 100 102
|
|
print(hero_state) # 1
|
|
print(Position.count()) # 2: the player and the thing spawned after
|
|
}
|
|
if frames == 3 {
|
|
print(Hero.of(player).flash) # ticked twice: 1
|
|
Position.despawn_all()
|
|
print(Position.count()) # 0
|
|
quit()
|
|
}
|
|
}
|
|
}
|