Lyric
We’ve released Lyric 1.1.1, and it introduces a major internal change to how the language executes programs.

Previous versions of Lyric executed code by walking the language’s abstract syntax tree directly.

Lyric now includes a transpiler backend that converts the Lyric AST into a Python AST, which is then compiled into Python bytecode using CPython’s native compiler. In practical terms, Lyric programs are now executed by the CPython virtual machine rather than by Lyric’s own AST-walking interpreter.

This change resulted in significant performance improvements in our benchmarks and greatly simplifies the runtime execution model. The interpreter mode still exists for development and the REPL, but the transpiler path is now the primary execution engine.

During this work we revisted our earlier benchmarks from October and quickly realized that Lyric did not, in fact, outperform Python. Lyric was running the smaller test and was compared against Python running 100x times operations. Python in fact smoked Lyric accross the board in apples to apples comparison. The old journal post with the erroneous claim has been removed and will not be saved here.

This release improves our performance dramatically and we are catching up on Perl with these improvements. You can view the results of the performance tests in the README.md file in Lyric's public source repository.

This release also lays important groundwork for future work on the language, including the addition of semantic analysis and a longer-term goal of supporting a native LLVM backend. Lyric's syntax is well suited for compiled code although var and importpy will not likely be supported.

Lyric continues to evolve as an experimental language project here at MiraNova, and this release marks an important step toward a more mature compiler architecture.

Note from Claude

Here is a note from Claude on our implementation.

  1. Lyric source → lexer.py tokenizes it
  2. Lexer → parser.py builds the Lyric AST
  3. Parser → compiler.py walks the Lyric AST and emits Python ast module nodes
  4. Compiler → Python's built-in compile() turns the Python AST into CPython bytecode
  5. CPython bytecode → exec() runs it on CPython's C-level VM

The only thing worth noting is that step 4 and 5 are handled by CPython itself — we hand it a Python AST and CPython does the rest. We never touch raw bytecode directly. That's the beauty of it — we get bytecode-speed execution without having to build our own VM.

MikoPoker
Work on MikoPoker has also accelerated significantly.

The game has now been fully ported from Cocos Creator to PixiJS v8. Rather than attempting a partial migration, the entire UI layer was rebuilt from scratch — including scenes, components, card animations, responsive scaling, and the general rendering pipeline.

During the port, the engine’s side pot logic was rewritten, resolving several bugs that had surfaced in earlier versions. The game now also includes a roster of 32 named AI opponents, each with distinct playstyles, bringing much more personality to the table.

A number of gameplay touches have been added as well: deal-for-the-button ceremonies, pre-action buttons, and animated pot-to-winner fly effects that make the table feel far more alive.

What makes this milestone particularly remarkable is the speed of the transition. The project went from zero PixiJS code to a fully playable eight-seat Texas Hold’em game in roughly a day, which is a testament to how well the new engine approach fits the project.

As always, development at MiraNova tends to move quickly and a little unpredictably — but both Lyric and MikoPoker are now on much stronger technical foundations than they were just a short time ago.

-- Michael (Aeonath)