Snake
Snake is a full multiplayer Slither.io running inside the Snapchat camera. You are permanently moving forward; the joystick only steers, and a dash button trades mass for speed: boosting literally burns your score and drops it behind you as food for everyone else.
It is the oldest of the three projects and the one everything else grew out of. The Connected Lens session handling, the networked player prefab, the host-simulated bots and the core bandwidth principle were all established here, then carried forward essentially unchanged.
The game
- 01
You move forward constantly at 250 cm/s. The joystick steers your heading; it never stops you.
- 02
Eat glowing orbs scattered across the field. Each one adds a body segment and a point.
- 03
Hold dash for a 1.85× speed burst that drains 6 points per second, and the mass you burn drops behind you as food.
- 04
Cut in front of another player so they run into your body. Your own body can never kill you.
- 05
Die and your score resets to zero, dropping up to 20 orbs along your corpse for everyone else.
Constant forward motion with joystick steering, plus a dash button. There is no brake and no reverse; the only input that matters is where you point.
Raw orbs eaten. Body length follows the score directly (3 base segments plus one per point, capped at 60), so how big you look is how well you are doing. Milestone banners fire into the shared event feed at fixed score steps with escalating emoji.
Heading into another player's body kills you. The death sequence runs a two-second death cam while your body shrinks under a grey veil, then fades to black. The respawn happens behind the fade so you never see the world reset.
Endless. Players drop in and out freely and the leaderboard is the running goal; a timed-match mode exists in code but ships disabled.
Five in one session: three host-simulated bots and two live players, ranked purely on orbs eaten
The field border, a fog wall enforced by clamping position rather than by a physics collider
The tapered orb chain, rebuilt locally on every client from nothing but the synced head position
Multiplayer architecture
A Connected Lens session over Snap's Connected Framework: SessionController, SyncEntity, StorageProperty and Instantiator. Each client owns its own snake; the host simulates the bots, tops up the food supply and drives the shared state machine. There is no dedicated server: authority is split by concern rather than centralised.
- →Its own head position and heading
- →Its own score and the orbs it eats
- →Its own death and respawn
- →Its own boost state
- →All bot snakes: steering, eating and death
- →Food top-up on the field
- →The game state machine
- →Match restart
| Channel | Owner | Payload | Cadence |
|---|---|---|---|
| botState | BotManager | All bots' position, heading and score in one packet | 0.15 s |
| score | Leaderboard | Own score | Heartbeat |
| deathDrop | PointsSpawner | Every drop position from one death in a single event | On death |
| deathDropEaten | PointsSpawner | Pickup id | On pickup |
| grace | SnakeBodyManager | Spawn-invulnerability window | On respawn |
| death | SnakeBodyManager | This connection is now a harmless corpse | On death |
| boost | SnakeBodyManager | Boost glow on/off | On change |
| currentState | GameStatesSynchronizer | State machine index via StorageProperty | Host-gated |
A snake body can be sixty segments long, and there can be seven snakes on the field. Networking that would be hopeless. Instead every client reconstructs every remote body locally by following that player's already-synced head position through its travelled path, so the segments cost nothing on the wire.
The segments themselves are purely local visuals on every client and add zero network traffic (no realtime-store flooding).Project source
Dying scatters up to twenty food orbs at once. Creating twenty networked objects in one frame floods the realtime store and drops the connection, and staggering them over several seconds looks broken. The dying client instead broadcasts a single event containing every drop position, and each client spawns plain local orbs from it.
A multiplayer Lens with nobody in it is a dead Lens. Three AI snakes are simulated entirely by the host across cruise, hunt and attack modes, and broadcast as one compact packet roughly seven times a second. To every other client they are indistinguishable from players.
Engineering highlights
A chain of glowing orbs following the head's travelled path, tapered from head to tail and fading in colour as it goes. Unlike the two later projects there is no procedural mesh work here; segments are instanced sphere visuals with per-segment cloned materials.
- ·Head segment 55 cm, tail scaled to 0.35
- ·Colour fades 55% toward the tail, with optional two-tone banding
- ·12 cm sample spacing at 0.82 overlap for a continuous tube
- ·Length = 3 + 1 per point, hard-capped at 60 segments
Two hundred orbs stay live on the field, topped up by the host at no more than four spawns per half-second tick so the realtime store is never flooded. Each orb carries a glow halo, and because a death drops twenty orbs into a tight cluster, neighbouring halos dim each other so the pile does not blow out to solid white.
Nothing in the UI is a designed asset. The loading screen animates a rainbow snake of glowing orbs wiggling across the display beneath a pulsing title, and each leaderboard row builds its own dark-glass card with a circular avatar backdrop in code: 430 lines of it, the most elaborate of the three projects.
Custom Lens Studio shader graphs in the 5.21 format: an orb shader with vertex deformation and custom pixel shading, a LUT-based colour grade, and a PBR base, plus nine inherited resource shaders covering Bitmoji, hologram, blur and the connection-lost post effect.
What broke, and why
Every entry below is a real failure that shaped the code. They are documented in the project source itself, next to the fix.
The dash button was wired to a speed multiplier, but the drain logic ran against the same value that fed movement, so spending mass to go faster actually left you slower than a player who never touched it.
Separated the drain from the speed term so boost applies a clean 1.85× multiplier while mass burns off independently.
A dying snake's body stayed collidable for the length of the death animation. Anyone rushing in to grab the twenty orbs it had just dropped ran straight into a frozen corpse and died to a player who was no longer in the game.
A networked death event marks that connection harmless on every client the instant it dies, and the grace event takes over when it respawns. This became the pattern both later projects inherited.
Tapping during startup, while the free-placement reconfiguration was still running, lost the touch-end event. The joystick latched a direction and the player kept moving with an unresponsive control.
Gate the joystick off through the opening sequence, reconfigure while it is disabled, then re-enable. The same fix had to be carried into both later projects.
Lens Studio loads a variable TTF as a single face, its default instance, so the runtime text weight control has nothing to pick from and every heading renders identically.
Ship static instances generated with fontTools varLib.instancer at four weights and register them, so the code can request a weight and get one.
- Platform
- Snapchat in-camera Lens
- Clients
- Mobile · Camera Kit
- Contexts
- Live camera · Reply camera · Video chat
- Lens Studio
- 5.21.0
- Tracking
- None (synthetic 3D world, front and back camera)
- Session
- Remote / matchmade
- Players
- 2–4 matchmade
- Bots
- 3 host-simulated
- Offline
- Mocked singleplayer session