codebase gaps are pretty clear: almost everything. For gameplay I only have Create/Destroy/Enable/Disable object blocks and variable blocks, and reload scene. The rest is debugging and foundation. LunyScript supports For/If/While blocks, global and local variables, and coroutines, next to engine events (Update, Heartbeat). LunyScript execute for objects with matching names upon scene load and on instantiate. I want to allow for pattern matching so we can have numbered enemies. A Unity project with many Kenney assets already integrated exists.
question is whether we’ll need a statemachine if not behaviour tree implementations for the demo? otherwise it’s mainly the basics: input (action maps, not direct input), ui label + data binding (via variables), audio and vfx (could simply instantiate auto-play/auto-destroy prefabs for these, at first), … what else?
if it still makes sense for you to look at the codebase to understand the architecture and LunyScript builder patterns, go ahead and read it
i’d like a prioritized 2-week implementation plan
Let me examine the codebase to understand your architecture and builder patterns, then create the implementation plan.Perfect. Now I understand your architecture. Let me create a prioritized 2-week implementation plan focused on the survivor demo.## Architecture Understanding
Your LunyScript builder pattern is elegant:
Timer, Counter, On, Object)Var/GVar accessorsGaps for survivor demo (as you noted):
Re: StateMachine/BehaviorTree: For a survivor demo, you don’t need FSM or BT initially. Enemy AI can be:
You could add FSM for player states (idle/moving/attacking/dead) but even that’s overkill for MVP.
Philosophy: Implement minimum viable blocks to make gameplay functional, defer polish/debugging tools.
Goal: Player can move with WASD/arrows
Implementation:
Input.Action("Move").Do(blocks)
Input.Action("Move").Value() // returns Vector2
GetActionValue(string actionName), IsActionPressed(string actionName)InputActionBlock (condition): checks if action is activeInputActionValueBlock (variable): returns Vector2/float valueDeliverable: Script moves player via On.FrameUpdate(Object.Move(Input.Action("Move").Value()))
Goal: Objects can move, rotate, face direction
Implementation:
Transform.Move(direction, speed)
Transform.LookAt(target) // or LookDirection(vector)
Transform.Position() // returns Vector3 variable
ILunyTransform interface with Position, Rotation, LocalScaleTransformMoveBlock: translates object by direction * speed * deltaTimeTransformLookAtBlock: rotates to face target/directionTransformPositionBlock: returns position as VariableDeliverable: Player moves in 8 directions, enemies move toward player
Goal: Enemies spawn at random positions, waves increase
Implementation:
Random.Int(min, max) // returns variable
Random.Float(min, max)
Random.Vector3(minX, maxX, minY, maxY, minZ, maxZ) // for spawn positions
Random.Choice(options) // for enemy types
Object.Create("Enemy").From("Prefabs/Enemy").At(position).Do()
Deliverable: Enemies spawn in random positions around arena edge
Goal: Track score, wave number, enemy count
Implementation:
Var["score"].Add(10), Var["wave"].Increment()Timer("WaveSpawner").Every(30).Seconds().Do(
GVar["wave"].Increment(),
Counter("SpawnEnemies").Every(1).Seconds()
.For(GVar["wave"].Multiply(5)) // 5 enemies per wave, scaled
.Do(Prefab.Instantiate("Enemy").At(Random.Vector3(...)))
)
Deliverable: Wave-based enemy spawning with difficulty curve
Goal: Player shoots projectiles, enemies take damage and die
Implementation:
Physics.OnCollision(Object.Destroy()) // when this object collides
Physics.OnTriggerEnter(blocks) // for projectile hits
Object.HasTag("Enemy") condition blockOn.Created(Var["health"].Set(100))
On.TriggerEnter(
Var["health"].Subtract(10),
If(Var["health"].LessThan(0)).Then(Object.Destroy())
)
Deliverable: Projectiles damage enemies, enemies die
Goal: Basic juice (particles, sounds, score display)
Implementation:
// Prefabs auto-play and self-destruct
Prefab.Instantiate("VFX/Explosion").At(Object.Position())
Prefab.Instantiate("Audio/Hit") // instantiate at origin
UI.Text("ScoreLabel").Bind(GVar["score"]) // updates text every frame
UI.Text("WaveLabel").Bind("Wave: ", GVar["wave"]) // with prefix
UpdateText(string labelName, string value)Deliverable: Score/wave display, hit effects with particles/audio
Goal: Enemies chase player, player auto-fires
Implementation:
Transform.MoveToward(targetName, speed) // moves toward named object
Transform.DirectionTo(targetName) // returns normalized vector
On.FrameUpdate(Transform.MoveToward("Player", 2.0))
Counter("AutoFire").Every(10).Frames().Do(
Prefab.Instantiate("Projectile")
.At(Object.Position())
.WithRotation(Transform.Rotation())
)
On.Ready(Transform.Move(Transform.Forward(), 10)) // move in forward direction
Timer("Lifetime").In(3).Seconds().Do(Object.Destroy())
Deliverable: Functional combat loop
Goal: Playable demo in Unity
Deliverable: 2-minute gameplay video ready
Must-have (Week 1):
Must-have (Week 2):
Nice-to-have (defer if time):
Pattern matching for numbered enemies:
Enemy* matches Enemy_0, Enemy_1)StateMachine/BehaviorTree:
Unity project with Kenney assets:
If running behind:
Core MVP: Player moves, enemies spawn and chase, player kills enemies. That’s your Epic submission minimum.
—## Summary
2-Week Plan:
Day-by-day breakdown ensures you hit milestones without scope creep.
Your questions answered:
Next steps:
Does this plan work for you? Should I proceed with Day 1: Input API architecture?
Continued in => LunyScript_Demo_Plan_Feb+Mar_2026__Input.md