Instructions to use zsla-oc/laya-frogger with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Laya
How to use zsla-oc/laya-frogger with Laya:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
laya-frogger
Laya fine-tuned to play Frogger from a JSON description of the board. Each tick it picks one of five moves in a single forward pass.
Test level 4, never seen in training, at 12 moves a second. Right: the model's probability for each move, the planner's optimal moves (★) and per-decision latency.
| Base model | convaiinnovations/laya, ModernBERT-large encoder, 421M parameters |
| Task | choose the next move: up, down, left, right or wait |
| Input | a JSON state in a frog-centred view (at most 313 tokens with the question) |
| Output | one probability per move |
| Speed | 5.6 ms per decision on an RTX 5080 (fast=True) |
Results
50 test levels never seen in training, each with 5 homes and 3 lives:
| Policy | Games | Homes | Deaths | Optimal moves¹ | Fatal moves¹ |
|---|---|---|---|---|---|
| Base Laya, zero-shot | 3 | 0 / 15 | 9 | 0.664² | 0.306² |
| Always press up | 0.689 | 0.285 | |||
| This model | 50 | 208 / 250 | 91 | 0.938 | 0.002 |
¹ Share of 5,000 test states where the move is one the planner rates optimal, or where it dies or leaves no way home in time.
² On 500 test states. Zero-shot, the base model answers up every time and
dies within 13 moves.
Findings
- The state representation mattered most. On the same states and labels, a version that saw the whole board, one string per row, barely beat always pressing up. A frog-centred window that also shows each row one tick ahead took it to 0.94 optimal moves.
- Self-play data fixed play, not accuracy. Adding states from the model's own games, labelled by the planner (DAgger), lifted games from 182 to 208 homes and ended drowning, while test-set accuracy barely moved.
- One failure remains. 79 of the 91 deaths are the same mistake: hopping onto a log that carries the frog off the board on the next tick. That situation is only 0.1% of the training data.
Usage
import laya
QUESTION = {
"move": {
"type": "choice",
"instructions": (
"Which move gets the frog into an empty home "
"soonest without dying?"
),
"criteria": {
"up": "hop one row up, toward the homes",
"down": "hop one row down, back toward the start",
"left": "hop one cell left",
"right": "hop one cell right",
"wait": "stay in place for this tick",
},
}
}
# a real state from a test level (format below)
state = {
"rows_to_home": 11,
"time_left": 58,
"empty_homes_dx": [-6, -3, 0, 3, 6],
"rows": [
"+3 road >3: now C C . . . C C . . | next C C C . . . C C .",
"+2 road >3: now . . C . . . . . C | next . . . C . . . . .",
"+1 road <3: now . . C . . . . . . | next . C . . . . . . C",
"+0 road <3: now . . C C F . . . . | next . . C C . . . . .",
"-1 safe: now . . . . . . . . . | next . . . . . . . . .",
],
"legend": (
"rows relative to the frog, +1 is the row above. "
"Each row shows the 9 cells centred on the frog "
"now and after the next tick. "
"F frog, C car, = log, ~ water, H empty home, "
"X filled home, # hedge, | edge of the board"
),
}
# fast=True needs tilelang; leave it out to use the stock forward pass
agent = laya.Agent("zsla-oc/laya-frogger", device="cuda", fast=True)
answer = agent.predict(state, QUESTION)["answers"]["move"]
print(answer["choice"], answer["probabilities"])
Send the question and the legend exactly as written; the model was trained on them.
State format
The board is 13 columns wide. Row 0 is the start, rows 1-5 are road, row 6 is a safe median, rows 7-11 are river, and row 12 holds homes at columns 0, 3, 6, 9 and 12. Each lane shifts one cell every 1-4 ticks.
| Field | Meaning |
|---|---|
rows_to_home |
12 minus the frog's row |
time_left |
ticks left in this life, out of 60 |
empty_homes_dx |
column offset from the frog to each empty home |
rows |
rows from 3 above the frog to 1 below, clipped to the board, top first |
legend |
fixed text, shown above |
Each row reads <offset> <kind> <motion>: now <9 cells> | next <9 cells>:
- offset is the row relative to the frog's (
+1is the row above). - kind is
road,river,safeorhome. - motion, on moving lanes only, is
<Nor>N: one cell left or right every N ticks. - now is the 9 cells centred on the frog, with
Fin the middle of the frog's own row. next is the same cells after the world moves one tick.
| Symbol | F |
C |
= |
~ |
H |
X |
# |
. |
| |
|---|---|---|---|---|---|---|---|---|---|
| Meaning | frog | car | log | water | empty home | filled home | hedge | ground | off the board |
A single | also separates the now and next frames.
Training
| Stage | Starting point and data | Epochs | Minutes |
|---|---|---|---|
| 1 | Base model. 49,946 states from 2,000 random levels, played by the planner with random moves mixed in | 2 | 32 |
| 2 | Stage 1. The same states plus 32,018 from stage 1's own games (DAgger) | 1 | 24 |
- Labels: an exact planner solves each life with one backward pass and marks every move that reaches a home fastest; tied moves share the probability. All data is synthetic, and no test level appears in training.
- Recipe: Laya's official fine-tuning notebook, ported to one GPU: soft-label cross-entropy plus the RLCD proper-scoring term, encoder learning rate 2.5e-5, head 1e-4, bf16, then a temperature fitted on 400 held-out states.
- Hardware: one RTX 5080. The run history is also stored under
traininginrl_agent_config.json.
Latency
Median per decision on an RTX 5080:
laya.Agent option |
Median |
|---|---|
| default | 14.4 ms |
compile=True (torch.compile) |
7.7 ms |
fast=True (TileLang kernels, CUDA graphs) |
5.6 ms |
Under WSL2, after about 1.5 s idle the GPU dropped into a power state where decisions took 27 ms, and it stayed there under light load. A 50 ms burst of back-to-back calls restored full speed. If you call the model a few times a second, check for this.
Limitations
- Trained and evaluated once, with no error bars, on 50 test levels.
- The frog-centred view hides rows the planner can see, so perfect play isn't reachable with this input.
- Only meaningful for this Frogger and this state format: a study of fine-tuning a decision model, not a general game-playing model.
Licence
Apache 2.0, like the base model convaiinnovations/laya by Convai Innovations. Its encoder is ModernBERT-large by Answer.AI.
- Downloads last month
- -
Model tree for zsla-oc/laya-frogger
Base model
convaiinnovations/laya