<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: vinny</title>
    <description>The latest articles on DEV Community by vinny (@vinny_0f23e2d307e45b62614).</description>
    <link>https://dev.to/vinny_0f23e2d307e45b62614</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3980106%2F694d74a8-ae2b-4f3e-a506-2b9daf7a8743.png</url>
      <title>DEV Community: vinny</title>
      <link>https://dev.to/vinny_0f23e2d307e45b62614</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vinny_0f23e2d307e45b62614"/>
    <language>en</language>
    <item>
      <title>Solstice — A Light-Routing Puzzle Game</title>
      <dc:creator>vinny</dc:creator>
      <pubDate>Sun, 21 Jun 2026 17:15:40 +0000</pubDate>
      <link>https://dev.to/vinny_0f23e2d307e45b62614/solstice-a-light-routing-puzzle-game-1827</link>
      <guid>https://dev.to/vinny_0f23e2d307e45b62614/solstice-a-light-routing-puzzle-game-1827</guid>
      <description>&lt;h2&gt;
  
  
  tags: dev-challenge, game-challenge, gamedev
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Built&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Solstice is a puzzle game where you place mirrors to guide light beams across a grid. Each level has two modes — SUN and MOON. You toggle between them to route both beams to their targets. Both need to be lit at the same time to win.&lt;/p&gt;

&lt;p&gt;Click a cell to place a &lt;code&gt;/&lt;/code&gt; mirror, click again for &lt;code&gt;\&lt;/code&gt;, again to remove. Right-click removes it. Ctrl+Z to undo. That's the whole mechanic — but the levels get hard fast.&lt;/p&gt;

&lt;p&gt;There are 18 levels split into 7 tiers. It starts simple (one mirror, one beam) and builds up to puzzles where you have fewer than 10 free cells and every placement has to count. I verified every level with a Python solver to make sure they're all solvable at the stated par.&lt;/p&gt;

&lt;p&gt;The game has a terminal with a Bletchley Park theme. You get 3 questions, the AI responds like a trapped wartime consciousness, and at the end you decide if it was human or machine. It connects to the Gemini API if you have a key, otherwise it uses pre-written responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VIDEO DEMO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gqtylwILuJ8"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Code&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jacksonvincent012-web" rel="noopener noreferrer"&gt;
        jacksonvincent012-web
      &lt;/a&gt; / &lt;a href="https://github.com/jacksonvincent012-web/Solstice-Game" rel="noopener noreferrer"&gt;
        Solstice-Game
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Solstice&lt;/h1&gt;
&lt;/div&gt;
&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/238323231/608065864-4a8258fd-2744-474f-98d4-f0b6a29cabe3.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODIwNjU1MDEsIm5iZiI6MTc4MjA2NTIwMSwicGF0aCI6Ii8yMzgzMjMyMzEvNjA4MDY1ODY0LTRhODI1OGZkLTI3NDQtNDc0Zi05OGQ0LWYwYjZhMjljYWJlMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNjIxJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDYyMVQxODA2NDFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yMmE2OTM3OTBhYjEzYjM4NDE0NDUyODFhNGI5NjVhZGExYmZmYjA4N2FmMDc0NzM2OTM1MTM0NzZiMGZhODJiJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.VfIS8aufrAHMZpKFtKmi87mVirvjyF0eEeyVec0AoGQ"&gt;&lt;img width="1920" height="1032" alt="Screenshot 2026-06-15 202114" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F238323231%2F608065864-4a8258fd-2744-474f-98d4-f0b6a29cabe3.png%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODIwNjU1MDEsIm5iZiI6MTc4MjA2NTIwMSwicGF0aCI6Ii8yMzgzMjMyMzEvNjA4MDY1ODY0LTRhODI1OGZkLTI3NDQtNDc0Zi05OGQ0LWYwYjZhMjljYWJlMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNjIxJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDYyMVQxODA2NDFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0yMmE2OTM3OTBhYjEzYjM4NDE0NDUyODFhNGI5NjVhZGExYmZmYjA4N2FmMDc0NzM2OTM1MTM0NzZiMGZhODJiJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.VfIS8aufrAHMZpKFtKmi87mVirvjyF0eEeyVec0AoGQ" class="js-gh-image-fallback"&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;A light-routing puzzle game with a custom ray-tracing engine, dual-spectrum beam physics, 18 levels across 7 tiers, a CRT terminal narrative, undo/redo, and a star-based rating system.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Built with vanilla JavaScript, rendered on HTML Canvas 2D, with audio synthesis via the Web Audio API and optional AI-powered dialogue through Google Gemini. Deployed as a static site on the Vercel CDN.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://solstice-game-pi.vercel.app" rel="nofollow noopener noreferrer"&gt;solstice-game-pi.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Each subsystem is a standalone ES module communicating through a central game state, orchestrated by a &lt;code&gt;requestAnimationFrame&lt;/code&gt; game loop.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Core Rendering Pipeline&lt;/h3&gt;
&lt;/div&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;flowchart LR
    subgraph Pipeline[Core Pipeline]
        direction LR
        GL["GAME LOOP&amp;lt;br&amp;gt;main.js&amp;lt;br&amp;gt;requestAnimationFrame&amp;lt;br&amp;gt;renderer.draw()&amp;lt;br&amp;gt;updateUI()"]
        RT["RAY TRACER&amp;lt;br&amp;gt;raytracer.js&amp;lt;br&amp;gt;Dual-pass simulation&amp;lt;br&amp;gt;SUN + MOON paths&amp;lt;br&amp;gt;Cycle detection"]
        RD["RENDERER&amp;lt;br&amp;gt;renderer.js&amp;lt;br&amp;gt;3-pass canvas draw&amp;lt;br&amp;gt;Glow + dashes + pulses&amp;lt;br&amp;gt;Particle integration"]
        PS["PARTICLES&amp;lt;br&amp;gt;particles.js&amp;lt;br&amp;gt;emit() / burst()&amp;lt;br&amp;gt;update(dt) / draw()&amp;lt;br&amp;gt;Lifecycle management"]
    end

    GL --&amp;gt; RT --&amp;gt; RD --&amp;gt; PS

    style GL fill:#1a1a3a,stroke:#ffd700,color:#ffd700
    style RT fill:#1a1a3a,stroke:#4a90d9,color:#4a90d9
    style RD fill:#1a1a3a,stroke:#7b68ee,color:#7b68ee
    style PS fill:#1a1a3a,stroke:#00ff88,color:#00ff88
    style Pipeline fill:#0a0a1a,stroke:#333,color:#888
&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full"&gt;
    &lt;span&gt;
      &lt;span class="sr-only"&gt;Loading&lt;/span&gt;
&lt;/span&gt;
  &lt;/span&gt;


&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Supporting Systems&lt;/h3&gt;

&lt;/div&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;flowchart TB
    subgraph Systems[Supporting Systems]
        direction TB
        IM["INPUT&amp;lt;br&amp;gt;input.js&amp;lt;br&amp;gt;Mouse +&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jacksonvincent012-web/Solstice-Game" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Play it here: &lt;a href="https://solstice-game-pi.vercel.app" rel="noopener noreferrer"&gt;https://solstice-game-pi.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HOW I BUILT IT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vanilla JavaScript with HTML Canvas for rendering. No frameworks, no libraries — just ES modules and the Canvas 2D API.&lt;/p&gt;

&lt;p&gt;The ray tracer uses grid-based ray marching. Each frame runs twice — once for SUN, once for MOON. Mirrors transform the direction vector: &lt;code&gt;/&lt;/code&gt; does &lt;code&gt;[dx, dy] → [-dy, -dx]&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt; does &lt;code&gt;[dx, dy] → [dy, dx]&lt;/code&gt;. Cycle detection prevents infinite loops from mirror pairs facing each other.&lt;/p&gt;

&lt;p&gt;Audio is all Web Audio API oscillators — no sound files at all. The terminal uses the Gemini API when configured, with a system prompt that keeps the Bletchley persona consistent.&lt;/p&gt;

&lt;p&gt;Levels are hand-designed with increasing wall density. Levels 11-18 went through multiple redesigns after my Python solver kept finding unintended shortcuts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prize Category&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;BEST ODE TO ALAN TURING ;&lt;br&gt;
The terminal is a Turing Test. You talk to something that believes it was a code-breaker at Bletchley Park in 1945. Three questions, then you judge. The dialogue touches on Enigma, ration books, the hum of valves. The ending asks the same question Turing posed — can you tell the difference?&lt;/p&gt;

&lt;p&gt;Best Google AI Usage&lt;br&gt;
The terminal connects to the Gemini API for dynamic responses. The AI stays in character as a wartime consciousness. Without a key it falls back to pre-written dialogue, but with Gemini every conversation is unique.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
