How and why I developed “Soko64”, a Sokoban game for Commodore 64, in 2022

Read all posts about "" game

Sometimes the art of coding takes you to unexpected shores. This is why I wrote a Sokoban game for the Commodore 64.

How did it come to my mind? Back in the eighties, there was a magazine called Zzap!64 covering the best games for 8-bit computers like C64, Spectrum ZX and more. There also was an italian version of the magazine, which recently came back to life, and I have the honor of being one of the editors.

The 8-bit scene is incredibly exciting, with a lot of new games being released every week, and there are also many new tools for modern computers to develop 8-bit games.

One of them is ugBasic, a cross-platform language similar to good old BASIC. I tried it, and ended up building a Sokoban game.

I already built a lot of Sokoban games for various platforms in various languages, so I said to myself: why not? Although I can code a Sokoban game with my eyes closed, this time I ran into a series of problems, like low RAM, no tweening, and just a few colors.

But eventually, as usual, I managed to build a Sokoban game with 64 levels. How can you play, if you don’t have an actual C64 hardware? With emulator like VICE.

Look at the source code:

BITMAP ENABLE (2)
COLOR BORDER BLACK

DIM levels AS BYTE (2304) = #{_
0,0,1,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,1,4,2,1,3,0,0,0,0,1,0,0,0,0,0,1,1,1,_
1,0,0,0,0,1,1,3,0,2,0,1,0,0,4,0,0,1,0,3,1,2,0,1,0,0,1,1,1,1,1,1,1,1,1,1,_
2,0,1,1,1,1,2,0,1,1,1,1,4,3,0,0,1,1,0,3,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,_
2,0,4,0,0,1,0,0,3,3,0,1,1,1,0,2,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,0,0,5,4,1,1,0,0,3,2,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,1,_
0,0,1,1,1,1,0,4,1,1,1,1,2,3,1,1,1,1,0,0,0,0,1,1,2,3,1,0,1,1,1,0,0,0,1,1,_
1,0,0,0,0,1,0,0,1,1,0,1,0,3,2,3,2,0,1,0,1,0,0,0,1,0,4,0,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,1,1,3,2,4,0,0,0,0,1,0,0,0,0,3,2,0,1,0,0,1,0,0,1,1,1,1,0,0,1,_
1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,2,1,0,0,3,3,2,1,1,0,0,0,4,1,1,1,1,1,1,1,_
1,0,0,0,1,1,1,3,1,2,1,1,0,0,0,0,1,1,0,3,1,2,0,1,1,0,4,0,0,1,1,1,1,0,0,1,_
0,0,0,1,0,0,0,0,2,0,0,0,1,3,1,1,0,0,0,4,2,1,0,0,0,3,0,0,0,0,1,1,1,1,0,0,_
2,2,6,1,1,1,0,3,3,1,1,1,1,3,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,_
1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,0,3,3,3,0,1,0,2,6,2,0,1,1,1,1,1,1,1,_
0,0,1,1,1,1,0,0,0,0,1,1,0,3,2,0,1,1,1,0,5,0,1,1,1,3,2,0,1,1,1,0,4,1,1,1,_
1,0,0,0,0,1,1,0,1,0,0,1,2,5,1,0,0,1,2,0,1,0,1,1,4,3,3,0,0,0,0,0,1,0,0,0,_
1,0,0,0,0,1,1,0,2,2,2,1,0,3,3,3,0,1,0,4,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,_
0,2,2,0,0,1,0,2,4,3,0,1,1,0,3,3,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,_
0,4,1,1,1,1,0,0,1,1,1,1,3,3,3,0,0,1,2,2,2,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,_
1,1,0,6,0,1,1,1,0,5,0,1,0,0,3,5,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,_
0,0,1,1,1,1,0,0,1,1,1,1,0,0,3,0,0,1,1,3,5,2,0,1,0,0,2,0,1,1,0,0,4,0,1,1,_
0,0,0,0,0,1,2,1,0,1,0,1,0,3,3,2,0,1,2,0,0,1,1,1,0,1,3,1,1,1,0,0,4,1,1,1,_
1,0,0,0,0,1,1,0,2,2,2,1,0,3,3,0,3,1,4,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,_
1,1,0,0,1,1,2,0,3,0,3,0,4,1,0,0,1,0,0,1,3,2,2,0,0,0,0,1,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,1,2,3,0,1,1,0,3,2,4,1,1,0,2,3,0,1,1,0,0,1,1,1,1,0,0,1,1,1,1,_
0,0,0,1,1,1,0,0,0,1,1,1,1,3,3,0,3,0,1,2,2,0,2,0,1,0,0,1,1,1,1,4,0,1,1,1,_
1,0,0,1,1,1,0,0,0,1,1,1,0,5,2,4,0,1,1,3,5,0,0,1,0,0,0,1,1,1,0,0,0,1,1,1,_
1,1,0,0,1,1,1,1,3,0,1,1,0,6,5,2,0,1,0,0,3,0,0,1,0,0,0,1,1,1,0,0,0,1,1,1,_
1,1,0,0,0,1,1,0,0,1,0,1,1,6,3,5,5,1,0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1,1,1,_
0,0,1,0,0,0,0,2,0,0,2,2,0,0,0,1,1,1,0,3,3,3,0,1,1,1,4,0,0,1,1,1,1,1,1,1,_
1,1,0,0,1,1,0,0,0,0,1,1,0,3,0,3,0,1,0,0,1,3,4,1,2,2,2,0,1,1,1,1,1,1,1,1,_
1,0,0,1,1,1,1,0,0,0,0,0,1,3,2,2,0,2,0,0,1,1,4,1,0,3,3,0,0,1,0,0,0,0,0,1,_
0,2,1,1,1,1,0,2,1,1,1,1,3,0,0,3,4,0,0,0,0,3,0,0,2,0,1,1,1,1,1,1,1,1,1,1,_
1,1,1,1,4,0,1,1,0,0,0,0,0,3,3,1,2,0,2,0,0,0,0,1,0,3,0,1,0,1,1,1,0,0,2,1,_
0,0,0,1,1,1,0,1,0,1,1,1,0,0,0,1,1,1,5,6,3,5,0,1,0,0,0,0,0,1,1,1,1,0,0,1,_
1,1,1,0,0,1,0,0,2,3,0,1,0,0,2,3,4,1,1,1,2,3,1,1,1,1,0,0,1,1,1,1,0,0,1,1,_
0,0,1,1,1,1,0,3,2,0,1,1,0,0,3,2,1,1,1,3,2,0,1,1,1,4,0,1,1,1,1,0,0,1,1,1,_
1,1,1,0,0,1,0,0,1,0,0,1,0,0,3,3,3,0,4,2,2,0,2,0,1,1,1,0,0,1,1,1,1,1,1,1,_
0,0,1,1,1,1,0,2,2,0,4,0,0,3,0,1,1,0,1,0,0,1,1,0,1,3,2,0,3,0,1,0,0,1,1,1,_
1,1,0,0,1,1,1,1,0,3,1,1,0,0,3,2,3,0,0,0,2,4,2,0,1,0,0,0,1,1,1,1,1,1,1,1,_
0,0,0,0,1,1,0,0,2,0,0,1,1,3,5,3,0,1,1,0,2,4,1,1,1,1,0,0,1,1,1,1,1,1,1,1,_
1,1,0,2,0,1,1,1,3,2,0,1,0,0,0,2,0,1,0,3,3,0,0,1,1,0,4,1,1,1,1,1,1,1,1,1,_
0,0,0,0,1,1,4,3,3,0,1,1,1,3,2,2,1,1,1,0,2,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,_
0,0,0,0,0,1,0,1,3,2,0,1,0,0,3,2,1,1,1,1,3,2,1,1,1,1,4,0,1,1,1,1,0,0,1,1,_
1,1,0,4,1,1,0,0,5,0,1,1,0,0,5,2,0,1,0,0,5,3,0,1,0,0,0,1,1,1,1,1,1,1,1,1,_
1,1,1,0,0,0,1,1,1,4,1,0,0,0,0,0,3,0,0,1,2,2,2,1,0,3,0,1,3,1,1,1,0,0,0,1,_
1,0,0,1,1,1,0,0,0,1,1,1,0,0,5,3,4,0,0,0,2,5,0,0,1,1,0,0,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,1,1,4,0,1,1,1,1,3,5,1,1,0,0,5,2,0,0,0,0,0,0,0,0,0,0,1,1,1,1,_
0,0,1,1,1,1,0,2,3,2,1,1,0,0,3,0,0,0,1,1,0,0,4,2,1,1,3,0,1,1,1,1,0,0,1,1,_
1,2,0,0,2,1,0,2,0,1,0,1,0,0,0,3,0,1,0,3,1,3,1,1,1,0,4,0,1,1,1,1,1,1,1,1,_
0,0,2,0,0,1,0,1,5,1,0,1,5,0,3,0,0,1,0,0,4,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,_
2,0,0,1,1,1,2,1,0,1,1,1,0,0,0,3,0,1,0,3,3,2,0,1,0,0,4,1,1,1,1,1,1,1,1,1,_
0,0,0,1,1,1,0,1,0,1,1,1,0,1,6,0,1,1,0,3,5,3,0,1,0,0,2,0,0,1,1,1,1,0,0,1,_
1,1,0,0,1,1,1,1,0,2,1,1,1,1,3,0,3,0,0,4,0,3,1,0,0,1,2,2,0,0,0,0,0,1,1,1,_
1,1,0,0,1,1,0,0,0,5,1,1,0,1,0,2,1,1,0,0,4,3,1,1,1,1,0,5,0,1,1,1,0,0,0,1,_
1,1,1,0,0,1,0,0,1,3,2,1,0,0,0,3,2,1,0,0,1,3,2,1,1,0,1,0,0,1,1,0,0,4,0,1,_
1,0,0,1,1,1,1,3,0,0,0,1,1,4,3,2,0,1,1,3,1,2,1,1,0,0,0,2,1,1,0,0,0,0,1,1,_
1,1,0,0,1,1,1,0,3,0,1,1,0,2,3,2,1,1,0,0,3,2,0,1,1,1,4,0,0,1,1,1,1,0,0,1,_
1,1,1,1,0,0,1,0,4,0,0,0,0,5,5,5,2,0,0,0,3,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,1,1,0,0,0,0,0,3,3,5,0,0,0,2,4,2,0,1,0,0,1,1,1,1,1,1,1,1,1,1,_
1,1,0,0,1,1,1,1,2,4,2,0,0,0,3,2,1,0,0,0,0,3,0,0,1,1,1,0,3,1,1,1,1,0,0,1,_
1,0,2,0,1,1,1,4,0,3,1,1,0,0,5,0,0,0,0,5,0,5,0,0,1,0,0,0,1,1,1,1,1,1,1,1,_
1,0,0,0,1,1,1,3,1,0,1,1,0,4,0,0,1,1,0,1,0,2,1,1,2,3,3,2,0,1,1,1,0,0,0,1,_
0,0,0,0,0,1,0,1,0,1,0,1,0,2,0,3,2,0,1,1,3,5,3,0,1,1,0,2,0,1,1,1,1,4,0,1,_
1,0,0,0,0,1,1,3,1,1,2,1,1,0,1,1,2,1,0,0,0,3,2,0,0,3,0,0,4,0,1,1,0,0,1,1_
}

wallImage := LOAD IMAGE("images/wall.png")
playerImage := LOAD IMAGE("images/player.png")
crateImage := LOAD IMAGE("images/crate.png")
goalImage := LOAD IMAGE("images/goal.png")
floorImage := LOAD IMAGE("images/floor.png")
crateOnGoalImage := LOAD IMAGE("images/crate_in_place.png")
arrowImage := LOAD IMAGE("images/arrow.png")
lockedImage := LOAD IMAGE("images/locked.png")
unlockedImage := LOAD IMAGE("images/unlocked.png")

DIM levelArray AS BYTE (8, 8)
DIM solvedLevels AS BYTE WITH 0 (64) 
CONST floor = 0
CONST wall = 1
CONST goal = 2
CONST crate = 3
CONST player = 4

VAR level AS BYTE = 0 
VAR posX AS BYTE
VAR posY AS BYTE
VAR number
VAR playerX AS BYTE
VAR playerY AS BYTE
VAR destinationX AS BYTE
VAR destinationY AS BYTE 
VAR crateDestinationX AS BYTE
VAR crateDestinationY AS BYTE
VAR start AS BYTE

CLS
LOCATE 17, 6 : PRINT "SOKO64"
LOCATE 15, 10 : PRINT "PRESS FIRE"
LOCATE 9, 23 : PRINT "2022 Emanuele Feronato"
PUT IMAGE playerImage AT 120, 110
PUT IMAGE crateImage AT 152, 110
PUT IMAGE goalImage AT 184, 110
DO
	IF JFIRE(1) THEN
		EXIT
	ENDIF 
LOOP	
PUT IMAGE floorImage AT 120, 110
PUT IMAGE playerImage AT 136, 110
WAIT 100 MILLISECONDS
PUT IMAGE floorImage AT 136, 110
PUT IMAGE playerImage AT 152, 110
PUT IMAGE crateImage AT 168, 110
WAIT 100 MILLISECONDS
PUT IMAGE floorImage AT 152, 110
PUT IMAGE playerImage AT 168, 110
PUT IMAGE crateOnGoalImage AT 184, 110
WAIT 1000 MILLISECONDS

playLevel : 
	CLS
	IF level < 6 THEN
		start = 1
	ELSE
		start = level - 5
		IF start > 52 THEN
			start = 52
		ENDIF
	ENDIF		
	FOR i = 0 TO 12 
		IF start + i < 10 THEN
			LOCATE i * 3 + 1, 22 : PRINT "0"
			LOCATE i * 3 + 2, 22 : PRINT (start + i)	
		ELSE
			LOCATE i * 3 + 1, 22 : PRINT (start + i)
		ENDIF
		IF solvedLevels(start + i - 1) = 1 THEN
			PUT IMAGE unlockedImage AT 8 + 24 * i, 172
		ELSE
			PUT IMAGE lockedImage AT 8 + 24 * i, 172
		ENDIF		
	NEXT
	LOCATE 0, 0 : PRINT "(P)rev"	
	LOCATE 17, 0 : PRINT "(R)etry"	
	LOCATE 34, 0 : PRINT "(N)ext" 
	PUT IMAGE arrowImage AT 8 + 24 * (level - start + 1), 184
	posY = 48
	number = 36 * level
	posX = 96
	FOR i = 0 TO 7
		levelArray(0, i) = wall
		PUT IMAGE wallImage AT posX, 32
		levelArray(7, i) = wall
		PUT IMAGE wallImage AT posX, 144 
		ADD posX, 16
	NEXT
	FOR i = 1 TO 6	
		levelArray(i, 0) = wall
		PUT IMAGE wallImage AT 96, posY 
		levelArray(i, 7) = wall
		PUT IMAGE wallImage AT 208, posY
		posX = 112
		FOR j = 1 TO 6
			value = levels(number)
			levelArray(i, j) = floor
			IF value = wall THEN
				levelArray(i, j) = wall
				PUT IMAGE wallImage AT posX, posY
			ENDIF
			IF value = player THEN
				levelArray(i, j) = player
				PUT IMAGE playerImage AT posX, posY
				playerX = j
				playerY = i
			ENDIF
			IF value = player + goal THEN
				levelArray(i, j) = player + goal
				PUT IMAGE playerImage AT posX, posY
				playerX = j
				playerY = i
			ENDIF
			IF value = crate THEN
				levelArray(i, j) = crate
				PUT IMAGE crateImage AT posX, posY
			ENDIF
			IF value = goal THEN
				levelArray(i, j) = goal
				PUT IMAGE goalImage AT posX, posY
			ENDIF	
			IF value = crate + goal THEN
				levelArray(i, j) = crate + goal
				PUT IMAGE crateOnGoalImage AT posX, posY
			ENDIF	
			ADD posX, 16
			INC number
		NEXT
		ADD posY, 16
	NEXT
	
playerInput:  
	DO
		IF JLEFT(1) THEN
			destinationX = playerX - 1
			destinationY = playerY
			crateDestinationX = destinationX - 1
			crateDestinationY = destinationY
	  		GOTO movePlayer
		ENDIF
		IF JRIGHT(1) THEN
			destinationX = playerX + 1
			destinationY = playerY
			crateDestinationX = destinationX + 1
			crateDestinationY = destinationY
			GOTO movePlayer
		ENDIF
		IF JUP(1) THEN
			destinationX = playerX 
			destinationY = playerY - 1
			crateDestinationX = destinationX 
			crateDestinationY = destinationY - 1
			GOTO movePlayer
		ENDIF
		IF JDOWN(1) THEN
			destinationX = playerX 
			destinationY = playerY + 1
			crateDestinationX = destinationX
			crateDestinationY = destinationY + 1
			GOTO movePlayer
		ENDIF
		IF KEY STATE(KEY R) THEN
			GOTO playLevel
		ENDIF
		IF (KEY STATE(KEY P)) AND (level > 0) THEN	
			DEC level
			GOTO playLevel
		ENDIF
		IF (KEY STATE(KEY N)) AND (level < 63) THEN	
			INC level
			GOTO playLevel
		ENDIF
	LOOP
	
movePlayer :
	IF (levelArray(destinationY, destinationX) = goal) OR (levelArray(destinationY, destinationX) = floor) THEN
		IF levelArray(playerY, playerX) = player THEN
			PUT IMAGE floorImage AT playerX * 16 + 96 , playerY * 16 + 32
		ELSE
			PUT IMAGE goalImage AT playerX * 16 + 96 , playerY * 16 + 32
		ENDIF		
		ADD levelArray(playerY, playerX), - player
		playerX = destinationX
		playerY = destinationY
		ADD levelArray(destinationY, destinationX), player
    	PUT IMAGE playerImage AT playerX * 16 + 96, playerY * 16 + 32
    	WAIT 100 MILLISECONDS
    	GOTO playerInput
    ENDIF
    IF (levelArray(destinationY, destinationX) = crate) OR (levelArray(destinationY, destinationX) = crate + goal) THEN
		IF (levelArray(crateDestinationY, crateDestinationX) = goal) OR (levelArray(crateDestinationY, crateDestinationX) = floor) THEN
			IF levelArray(playerY, playerX) = player THEN
				PUT IMAGE floorImage AT playerX * 16 + 96 , playerY * 16 + 32
			ELSE
				PUT IMAGE goalImage AT playerX * 16 + 96 , playerY * 16 + 32
			ENDIF
			ADD levelArray(playerY, playerX), - player
			playerX = destinationX
			playerY = destinationY
			ADD levelArray(destinationY, destinationX), player
			ADD levelArray(destinationY, destinationX), -crate
			ADD levelArray(crateDestinationY, crateDestinationX), crate
	    	PUT IMAGE playerImage AT playerX * 16 + 96, playerY * 16 + 32
	    	IF levelArray(crateDestinationY, crateDestinationX) = crate + goal THEN
	    		PUT IMAGE crateOnGoalImage AT crateDestinationX * 16 + 96, crateDestinationY * 16 + 32
	    	ELSE
	    		PUT IMAGE crateImage AT crateDestinationX * 16 + 96, crateDestinationY * 16 + 32
	    	ENDIF
	    	FOR i = 0 TO 7
    	 		FOR j = 0 TO 7
    	 			IF (levelArray(i, j) = goal) OR (levelArray(i, j) = player + goal) THEN
    	 				WAIT 100 MILLISECONDS
	    				GOTO playerInput		
    	 			ENDIF
    	 		NEXT
    	 	NEXT
    	 	GOTO levelCompleted	
		ENDIF
	ENDIF
	GOTO playerInput
    
levelCompleted :
	LOCATE 17, 3 : PRINT "SOLVED!" 
	solvedLevels(level) = 1
	DO
		IF KEY STATE(KEY R) THEN
			GOTO playLevel
		ENDIF
		IF (KEY STATE(KEY P)) AND (level > 0) THEN	
			DEC level
			GOTO playLevel
		ENDIF
		IF (KEY STATE(KEY N)) AND (level < 63) THEN	
			INC level
			GOTO playLevel
		ENDIF
	LOOP

Tomorrow I will comment the source and upload the game to my itch page, meanwhile you can download the source code of the whole project and play with it.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers