{"slug": "playing-contra-with-decision-models", "title": "Playing Contra with decision models", "summary": "A fine-tuned Laya Multilingual model (322 million parameters) cleared the first level of NES Contra, boss included, in 69.40 game seconds, according to a write-up by Nishaanth Reddy, falling just short of the 68.40-second run by hosted Jev that he was trying to beat. Reddy trained Laya and Qwen3.5-4B on two DGX Spark machines using decisions from Jev, and the frozen Laya checkpoint cleared 3 of 5 final runs on 8 October 2026, with two ending in game over. A separate GPT-6 Luna attempt through Codex produced only partial runs, with a median decision call of 5.26 seconds to choose an action lasting about 0.10 game seconds.", "body_md": "# Playing Contra with decision models\n\nBy [Nishaanth Reddy](https://morethanamachine.com/authors/nishaanth-reddy/) · · updated \n\nAfter [trying decision models in Doom](https://morethanamachine.com/posts/jev-style-decisions-dgx-spark/#doom), I wanted one to finish the original NES Contra’s first level, boss included. Fine-tuned Laya got through in **69.40 game seconds**. My saved Jev run took **68.40**. Close, but I haven’t beaten it.\n\nThe four panels show Jev, Qwen and Laya’s best development run, plus Laya’s first failed final test. Settings differ across controllers. Playback follows game time, with decision pauses removed. Laya’s 69-second clear took 6 minutes 18 seconds to run.\n\nThe sidebars show the last reply’s top three action scores. These aren’t calibrated odds of success. Call times include network latency.\n\n## [00] Controls\n\n[Jev](https://typesafe.ai/blog/introducing-system-one-models-and-jev) scores a set of possible answers. I gave the controller 12 actions, including running, jumping and firing. Each choice lasts six frames.\n\nThe models read player, terrain and enemy data from game memory. They also get emulator previews of each move, which is a lot of help. Shooting actions pulse the fire button at 10 Hz. The verified clears use no cheats, continues or human takeover.\n\nI checked each clear by replaying the saved button inputs and confirming boss defeat followed by entry into Stage 2.\n\n## [01] Training\n\nI fine-tuned [Qwen3.5-4B](https://huggingface.co/Qwen/Qwen3.5-4B) on one DGX Spark and [Laya Multilingual](https://huggingface.co/convaiinnovations/laya-multilingual), with 322 million parameters, on the other. Qwen continued an existing low-rank adapter (LoRA). All training and local-model inference ran on the Sparks.\n\nHosted Jev supplied training decisions, including its 68.40-second run and labels for states where the local models got into trouble. I kept development and final test episodes out of the training updates. Jev itself was unchanged.\n\nOne mistake was in the loss function. It punished a move for a death predicted 39 frames later, even though the model could choose again after six. I shortened that penalty to the six frames the action would actually run.\n\n## [02] Results\n\nThese are selected successful runs from different development settings, so they aren’t a matched benchmark. Elapsed time includes decision waits and emulator work.\n\nLocal recordings, 7–8 October 2026.\n\n## Individual recordings\n\nA later Qwen checkpoint kept retreating at the boss and lost both development games. The video uses the earlier checkpoint that finished.\n\nLaya then cleared **3 of 5 final runs** with the checkpoint frozen. Each used a different starting delay on the same stage. Two ended in game over. The 69.40-second development run isn’t in this set.\n\nFive final attempts, 8 October 2026.\n\nI’d work on keeping it alive across more runs before trying to shave off another second.\n\n## [03] The Luna runs\n\nI also tried GPT-6 Luna through Codex using my ChatGPT Pro subscription on 7 October. I built a separate Decisions API adapter, but never made a live call through it. The saved gameplay came through Codex.\n\n| Attempt | Decisions | Game time | Outcome | \n|---|---|---|---|\n| Integration check | 10 | 1.00 s | Stopped at the test limit | \n| First longer attempt | 8 | 0.80 s | Request timed out | \n| Second longer attempt | 54 | 5.39 s | Paused at my request | \n\nThe longest attempt saved 324 frames. Its median decision call took **5.26 seconds**, including Codex overhead, to choose an action lasting about 0.10 game seconds. The saved replies contain a chosen move without action scores.\n\nThese are partial runs with no verified stage clear or full video. They aren’t included in the clear-time charts or the four-panel recording.", "url": "https://wpnews.pro/news/playing-contra-with-decision-models", "canonical_source": "https://morethanamachine.com/posts/contra-decision-models/", "published_at": "2026-10-08 00:00:00+00:00", "updated_at": "2026-10-26 20:41:46.808595+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "ai-research"], "entities": ["Laya Multilingual", "Qwen3.5-4B", "Jev", "Nishaanth Reddy", "DGX Spark", "GPT-6 Luna", "Codex", "Contra"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/playing-contra-with-decision-models", "markdown": "https://wpnews.pro/news/playing-contra-with-decision-models.md", "text": "https://wpnews.pro/news/playing-contra-with-decision-models.txt", "jsonld": "https://wpnews.pro/news/playing-contra-with-decision-models.jsonld"}}