
>
Tascii - ASCII Level Editor
So i'm working on my new PICO-8 game and i'm using ascii (rogue/nethack) type of level structure, which my code then converts to sprite based graphics on level load. Its not a big routine or complex, i set up a "legend" table, which co-relates each ASCII character to a sprite index and add those to the map in order. Nothing really fancy.
But as i started working on my levels, i noticed that none of the ASCII Level editors that i could find allowed me to copy the level inside an c-array or lua table, or similar. So i did what anyone would do, i decided to code my own level editor to use on this mini-game. It is very simple, specially on the interface, because the idea is to use to quickly design levels and export it to my game. You can drag the mouse to paint characters, and you can just press a key to change the "current tile" (aka the character) you're putting on the grid. All very quick and simple. But it works. Now i can focus on what is important, making the levels and finishing this game, hopefully on the next week or two.
You can use Tascii here:
http://tibone.itch.io/tascii
and get the code here:
https://github.com/jflores82/tascii
>
Data Filch - Post Mortem
I have made a game, from zero, and released it, in less than 30 days.
BUT, and there's always a BUT, it is a ridiculous tiny game, like tiny, TINY.
But, why? nobody asked. well, i needed to finish and release SOMETHING, anything, at this point in time.
Let's start by rewinding all way to last year.
At the beginning of the year, i created a game for the Thumby hardware, based on a video a friend showed me.
The hardware is really limited and it uses micropython, a subset of python to code, it was quick and fun, but calling it a complete game, eh, maybe not. But it is released and you can play it on your real Thumby or an emulator.
Then the string of failed projects started.
First a visual novel engine written in Javascript. I got it to a semi-working phase, even did a prototype little game for it.
But, felt i wasn't adding anything to the world, that RenPy couldn't do so much better. So, i scrapped that.
Then there was several ideas that i have semi-started, but never got off the ground, like doing a zelda-clone for the Sega Master System or something.
Then, the same friend saw another video and showed me Pico-8, which was cool, but i wasnt gonna buy it, but luckily for me, i had already bought it, on a bundle, way back in 2020. So, i started messing with Pico-8 and did this little shmup idea, which, of course, let the scope get way out of hand and made a mess out of it. But i did built a version with a single level on it.
Then, another idea, of a physics based side-scrolling little "shooter" for the Sega Master System, which i did a prototype, that has exactly 1 level. It is working, but also, now comes the parts that i dread the most, pixel art and level design, i always get burn out during those parts. So another little engine, another project stopped. I think i may pick this up again, for the march smspower compo.
Then, another idea, maybe i should learn Godot, build myself this little prototype, a single screen rpg, with random enemies and a battle system similar to Paper Mario. Guess what? I have a single level prototype running. It was good to start to understand Godot.
Back to Pico-8, because reasons, i started a new platformer game, did the very basic but i started to let scope creep get the better of me, once again. So.. you won't believe this.. but i have a single level demo done.
And that was the breaking point for me. So i decided, starting January, i'm going to start, finish and release a game. no matter what.
First things first, scope. I'm working alone, while also managing a full-time job, family and being a hobbyist musician sometimes.
I decided to clone an Atari 2600 game, after all, the last game i released, Raposa do Sol, was exactly that, a clone of an Atari 2600 game called Solar Fox. So this time, i decided to go with one of my all time favorites from the system, Dragonfire, developed by Activision.
Dragonfire is a very simple game. You have two screen, one is a side-view, where your only objective is to avoid the fireballs and get inside the castle, the next screen is a top-down view, and your only objective is collect the treasures to unlock the exit, and then reach it. Ok, simple enough.
I decided to do on Pico-8 because:
1) i want to learn it.
2) its limitations will help me avoid scope creep.
3) its all self-contained, i can create all the assets and code inside the same program.
4) its limitations will help me avoid scope creep.
So, i started building. There wasn't a lot to build, i took part of the code of my platformer-prototype and started there.
Pico-8 makes prototyping small ideas very quick, so within 2 days, i had a working prototype of the side-view part.
But then, scope started creeping in.. "what if i added scrolling to that?", well, i did just that. Added scrolling.
Now the top-down view part was even simpler to build than the side-view. I tried adding scrolling aswell, but it didn't felt right so i scratched that idea.
The next couple of days i spent making sure the mechanics were tweaked and fun to play, i wasnt aiming for a exact port of Dragonfire just something that i could build that was fun and that used those core mechanics.
Then the next couple of days were spent making the boring stuff and building the logic for it, title screen, deaths and loops, option screen, game over screen, etc. That went smoothly, and i knew i could finish in time. As long as i didn't changed/added mechanics, i could finish it in time.
Next part was a scoring system, i never liked that the original Dragonfire dont give you any points on the side view part of the game, so i added a scoring system, where you get rewarded by moving left and get points deducted by going left, also, i added a "danger" meter, which multiply points, if you get "near misses" in the side-view portion. For the top down, the original scoring system worked, so i haven't messed with it.
The next couple of days were spent on redrawing the graphics, i added the rain graphics on the side-view part, as a little something extra on top. and then added music and sfx.
So, about 25 days later, here it is: i called Data Filch. because i wanted something that kept the DragonFire initials and because my game is about a spy stealing data from a rival corporation.
And if you want to play this game, you can, right now, on my itch page.
So in the end, how deep is Data Filch? If i'm honest, its not very deep, its a simple 2 screen game loop with increased difficulty each loop and you're basically playing for score. But the game is done, released and i managed to keep the scope under control.
https://tibone.itch.io/datafilch
https://tibone.itch.io/datafilch
>
tiblognev - new version of this site - Post-Mortem - 2025/09/09
I have absolutely no idea if anyone reads this, and honestly at this point in my internet "career" i kinda really don't care.
I'm not doing this to please anyone else, except for myself, which is kinda egocentrical, but since nobody else cares, i also don't care that it is.
Anyway, i have made yet another change to backend of this site, which was previously built on a flatfile php blog system i came up in an afternoon, now i have upgrade to an all-new flatfile php blog system that i have built in an afternoon.
But there are a lot of key changes, and mostly its that this new system is completely
open source so you can go there and laugh at my code all you need.
This time, its built entirely using OOP and being modular and expansible enough that i can built upon the top of it, without having to re-build from scratch.
I already have some ideas on how to improve it, but we will see how that goes, let's not get ahead of ourselves.
So, about the code, if i show you the index.php of this very page, this is what you get:
require_once('class.tiblognev.php');
$blog = new tiblognev('tibonev dump of stuff');
$blog->render($_GET['p'] ?? null);
Yes, that is the entire index.php file. Its a very simples, we load a file into memory, instantiate the class, and call the render method, which can take an optional variable, in the form of a slug based on the filename of the post or if that isn't present, it pass a null.
Then the entire page is rendered.
But maybe i am getting ahead of myself, let's first take a look at the entire site file structure:
\posts\*.txt - each file here is a post.
\index.php - the file your browser runs.
\class.tiblognev.php - the backend engine.
\template_page.txt - this is the template of entire page, sans posts.
\template_posts.txt - this is the template of the posts, sans page.
As you can see, the engine takes the template_page.txt, look for the space dedicated to the posts, and then build each post based on the template_post.txt, puts all together and renders on the screen.
PHP is extremely fast with these kind of operations, usually this page loads in less than half a sec or under 500ms.
The render method also chooses between iterating all posts or a single post, if a slug (which is just the filename minus extension) is present as a parameter on the render method.
But, you're probably not asking yourself, how did you achieve that speed? Well, fear not, dear reader, for i am about to show you 2 neat tricks:
First one: Caching (insert sarcastic WOW sound here)
private function posts_process(): array {
if($this->posts_cache !== null) {
return $this->posts_cache;
}
...bunch of code..
$this->posts_cache = $posts;
return $posts;
}
Basically if i need to render several posts, my code iterates on the posts only once. because i do the most basic version of a cache known to man. I store the values i need on a variable and call that, and only run the rest of the function if my cache variable is empty.
Genius, right?
And the second trick is: stacking
private function post_style(array $post): string {
$template = $this->load_template($this->template_post);
return strtr($template, [
'%TITLE%' => $post['title'],
'%CONTENT%' => $post['content'],
'%FILENAME%' => $post['slug']
]);
}
Basically PHP allows me to stack the substr function via strtr, which allows me to stack all the replacements i need to, in a single call, making it cleaner and faster.
Now, does anyone care about this? Honestely, most like not, but if you're new to OOP or PHP and want to tackle a project that is easy to do, recreating this blog system might be a fun challenge.
Now, about this CRT effect? This is done entirely in CSS, with CSS Animations.
For the main scanlines, we do this:
.scanlines {
background: repeating-linear-gradient(transparent, transparent 2px, black 3px, black 3px);
background-size: auto 100%;
background-position: 0px 0px;
opacity: 0.5;
position:fixed;
left:0px;
top:0px;
width:100%;
height:100vh;
z-index:1000;
padding:0px;
margin:0px;
animation: scanlines-ani infinite 15s linear;
pointer-events: none;
}
@keyframes scanlines-ani {
from { background-position: 0 0; }
to { background-position: 0 100vh; }
}
So we basically created a venetian window, using a repeating-linear-gradient, and then we move it around the screen, at 15s per full motion.
For the upgoing grey line, is pretty much the same thing, but reversed:
@keyframes greyline-ani {
0% { top:100vh; opacity:0.02; }
100% { top:-1vh; }
}
We start at the bottom and go up slowly.
And finally for the glowing text, its a simple, static text-shadow call:
text-shadow: 0 0 5px #eeeeee; /* E E E its in the EEEEEEEEEEEEEE */
And that is it. That is how i did this page, this time. Will i change it in 6 months? There's a really good chance that yes, i will. But who knows? Not me.
Resources:
template_page.txt is avaiable at:
here
And the full thing is avaiable here:
here
>
Tinynvaders - A new Thumby Game - Post-Mortem
I don't remember the exact date, but a friend showed me, recently, a youtube video of someone showcasing the Thumby, which claims to be the world's smallest game console, with a whopping 29mm of size on the largest size,
the little thing seems pretty well built, and in the video, the youtuber showed that TinyCircuits, the company who makes the Thumby has a pretty good dev enviroment for it, support to code games in microPython, a c++ arduino library
and even a blockly editor. So, obviously that got my attention as in, can i make something for it? And since i've been wanting to get more practice in Python, why not? Thus, Tinynvaders was born.
Considering the Thumby only has a 70x40 monochrome display and monophonic sounds, it's not exactly a game that will blow anyones mind, its a simple infinite, horizontal shooting game, nothing to really write home about, except, that is exactly
what i am doing here, right?
I started by taking a look at the simple, but effective micropython API that is loaded into the Thumby, and within minutes i had something working, displaying a simple graphic. From there it was basically building up to a game.
The main gameplay is simple, you avoid being shot and you shoot the enemies. You can only move up/down and you can also load up a shield, if you kill 5 enemies. You can't accumulate shields, however.
Below is a code example, for my player control routine.
if thumby.buttonU.pressed():
if playery > bordert:
playery -= 1
playeranim += 1
#EndIf
#EndIf
if thumby.buttonD.pressed():
if playery < borderb:
playery += 1
playeranim += 1
#EndIf
#EndIf
if thumby.buttonA.justPressed():
if playercs == 0:
thumby.audio.play(440, 100)
playercs = 1
playersx = 3
playersy = playery
#EndIf
#EndIf
if thumby.buttonB.justPressed():
if playershieldstock == 1:
playershieldstock = 0
playershield = 1
thumby.audio.play(250, 50)
#EndIf
#EndIf
#EndDef
As you can see, the micropython API is very simple to use, and it doesn't take long to get something simple running on the device.
The graphics are built inside the dev enviroment, which is all browser based, so getting up and running takes literally no time.
The whole game is on my github page here: --
https://github.com/jflores82/TinyCircuits-Thumby-Games-- and you can check out more about Thumby at --
thumby.us--
This has been a fun little project, and i might even try more little thumby games in the future, especially if i manage to get my hands on the real hardware, who knows?
>
Simchecklists - Some webapp - PostMortem
Lately i've been playing a lot of flight simulators, specifically X-Plane 11 and more recently Microsoft Flight Simulator 2020.
Some of these sims are very in-depth, what some people like to call 'study-level' sims. So i started taking notes on a paper, with a pen.
After a while, i organized my notes, into something that started resembling the checklists that pilots use in real life, but still, more related to the sim.
And after looking for about 5 minutes on google, i couldn't find a simple app to build checklists and go through them with my phone as a side screen to the sim.
So, what did i decided to do? i decided to write something myself, because it is good practice, because its something that i'll use it myself and because why not?
and thus SimChecklists were born, as a small project to entertain myself, during lunchbreak, while i was trying to understand how to program the onboard computer on a Boeing 737-800.
I used PHP for most of the backend stuff, so sorting, parsing and delivering the checklists to the screen in a readable manner. With Vanilla Javascript for the frontend, interfacing with the user,
i wanted to avoid using anything heavy, so no images (only SVG icons dynamically loaded with PHP) and no 'javascript frameworks' (remember: no russian jquery). My main idea
was to keep everything as simple as possible, meaning its something lightweight, fast, easy to load, simple to use, and as barebones as it can be, just a way for me to keep track of a list while
also playing a flight simulator.
The main thing is that the checklists themselves are simple text files, i used a simple structure, using double dashs (--Foobar--) to denote a new sublist and foo=bar to denote items to do.
A simple js script to cross and mark the items as done once i clicked them and after less than 1 hour, i had a version 1 ready to upload, which i did.
I uploaded the app for myself, to use it on my own (this) domain. And i also uploaded the code to github, both to increase my portfolio and if anyone else wants to host it, modify or whatever, can
feel free to.
I also showed a friend, which gave a few suggestions. So i started implementing them, and this is actually a good reminder, for me, of how much i prefer working with vanilla js over jquery, it
as easy, but much faster and lighter weight and if'm honest, i think i did a good job.
At this moment i have a webapp that while not fully featured is really not that bad:
- Theme support through appropriated .thm files.
- Auto detection and theme switching between light and dark modes.
- Hability for the user to upload their own checklists, files gets verified in both extension and mime type formats.
- Auto-scroll the checklist on the screen as the items are clicked.
- Hability to swipe left on a checked item to uncheck it.
- User can choose a theme and the result is saved on a php_session (i wanted to avoid saving anything and i wanted to do something simple with no database.
The live app is here:
http://checklist.classicgames.com.br/
And you can check the code @
http://github.com/jflores82/simchecklists
This has been fun to do. And i've actually been using it. It reminds me of when i did Retroamp, so many years ago, but nowdays the core of the app isn't 'outsourced' to a library i haven't wrote,
all the lines of the code are 100% written by me. :)
>
Raposa do Sol - A new SMS Game (PostMortem)
Late january 2024, i remember that the SMS Power (www.smspower.org) anniversary competition is happening in march,
since i usually try to enter on the music competition, i thought to myself, what if i tried my hand at the coding competition instead?
might be cool to try and code something for my favorite console, for a change.
-- Part I: The Toolset --
I remember that there's a C devkit, appropriately named "devkitSMS", so i googled that and found the github for the devkit.
So i started reading what i'd need to install to make it work. There's SDCC (small devices c compiler) and the devkit itself. Ok seems simple enough.
Installed everything, run a test following the manual and it seems correct.
Went to the examples folder and there's something there to test.
Try to build the examples and it managed to get them both to run, nice, time to learn.
Or is it? Just realized i have no tools to make graphics or sounds.
devkitSMS seems to like files converted with Maxim's BMP2Tile, so downloaded that, but apparentely, it also needs another plugin, time to search for that.
Installed that, managed to get a very simple demo running.
Its just my logo, basically, graphics tools, check.
What i'll be using: Libresprite to draw, BMP2Tile to convert to SMS, seems good enough.
Its been a while that i've been wanting to learn Furnace, to write tracker music for the SMS, instead of using my 'usual' method of recording midi in the my daw,
converting to vgm, editing the vgm in mod2psg2, so i went to try and get, install and get a basic tutorial going.
Managed the very basic, so i guess its time to try my hand at adding sound to my logo demo.
Thanks to the PSGlib included in the devkitSMS, it was easy enough, a couple of minutes and lines of codes and i had my old western_sms.vgm song playing the same.
NOW it's time to learn.
-- Part II: First tests and coming up with an idea --
Next step, testing controllers.
Added a very badly made sprite over my logo background and made it move with the controller. Realized the sprite wraps around the screen when
going off-screen, might be easy to implement something like Asteroids, then? But i really wanted something a bit more involved and less cliché than
Asteroids. Maybe i should do Space Invaders? But there's already a good Space Invaders for the SMS, i'm sure.
So, time to start searching the web, 'best fixed screen games', 'famous arcade games' and so on. Nothing really grabs my attention. So i decided that i might
just convert an Atari2600 game, seems simple enough, but... which one? I know haroldoop did a very cool version of Turmoil, so that's out of question.
Kaboom might require more skills than i currently have, Enduro
definitely requires more skills than i currently have and the SMS already has Outrun,
Keystone Cappers requires more graphical skills than i have, Beamrider seems cool, might try to do that... but i realized that animating the background grid
with tile based graphics and my current skill set would take more time than i had (a little under two months before the SMSComp deadline).
Then, browsing youtube, i saw a game that might be a good fit, Solar Fox, an arcade game originally, with a slightly tweaked VCS port, that might be it.
Watched about 2hrs of gameplay, of both the original arcade and the VCS port, my feeling after it was: "i can do this", 100%.
But, i didn't want to do a port, i just want to inspire and get ideas and build my own game, so it begins, the coding of the Sega Master System "port" of Solar Fox.
-- Part III: SMS_setTileatXY ---
First things first, i start with a routine to draw walls on the 4 limits of the screen.
My very first initial idea was to use sprites for the walls, but it turned out to be a very bad idea, very quickly, since the walls won't move, there's no
reason to use them as sprites, instead of background tiles, so, that's what i did.
// Vertical Walls //
for(y = 0; y < 22; y++) {
SMS_setTileatXY(1,y,108);
SMS_setTileatXY(31,y,108);
}
// Horizontal Walls //
for(x = 0; x < 32; x++) {
SMS_setTileatXY(x,0,107);
SMS_setTileatXY(x,21,107);
}
// Corners //
SMS_setTileatXY(1,0,105);
SMS_setTileatXY(1,21,105);
SMS_setTileatXY(31,0,106);
SMS_setTileatXY(31,21,106);
That does it, pretty simple, two columns (vertical walls) and two lines (horizontal walls), with 4 decorative corner tiles, the beginning of a playfield.
And for the walls inside the playfield, i wrote a very simple routine to draw them, grabbing the location from the arrays, so i could design a proper level.
void walls_draw(void) {
for(int i = 0; i < level_walls_num; i++) {
SMS_setTileatXY(walls_x_y[i][0] / 8, walls_x_y[i][1] / 8, 100);
}
}
A very simple routine, but you might notice that i divided the value by 8, that's because, there's a difference between tile position and pixel position,
since i didn't realized that in the beginning, my arrays are storing pixel position for the X/Y of the walls, instead of tile position, and since each tile is 8x8 pixels, a very quick and dirty fix.
Now i had already had a ship, controlled by the player, and bound inside a playfield, with a couple of walls drawn in, time to write a collision detection routine.
That was the first 'obstacle' i encountered, because i knew, due to previous experiences writing other small games in other languages that collision detection could make the game craw to a halt,
specially since it is a routine that you need to check at least every other frame, in most cases of action games.
And since my wall locations were written inside arrays, that also meant i needed to loop the arrays.
Luckly for me, the little z80 could handle it like a champ.
This is what i came up with:
for(int i = 0; i < level_walls_num; i++) {
wall_x = walls_x_y[i][0];
wall_y = walls_x_y[i][1];
// collision bounderies //
if( pl_x < wall_x + 8 &&
pl_x + 16 > wall_x &&
pl_y < wall_y + 8 &&
pl_y + 16 > wall_y) {
...
It ssems to work, i can even call it up every single frame and since i'm not really re-drawing anything at the moment, it seems that i still have cpu cycles to spare.
And since it works, i used a similar collision check for the shots and the little 'satellites' which are called 'pellets' in the code, because i still wasn't sure what
to call them. :)
-- Part IV: random number is random --
One of the things that i've realized its very difficult to do on the SMS is random numbers, this is because the random seed for the rand() function in C
is generated at compile-time and not at run-time, which means that everytime, the rand() returns the same things, unless you re-compile the program, which is not
exactly viable, especially in a system like the SMS. But if you change the seed, you can simulate randomness, other way to simulate randomness is to generate a
random LUT and use that either as the seed or as the numbers themselves.
I took the first approach, basically i created an unsigned int and add to it every frame, until it reaches the int limit (no need to be a long, in this case, i think).
// For the random_level_generator //
unsigned int randomseed = 30; // Used to seed the rand command, 30 just being whatever to avoid starting at zero //
randomseed++;
if(randomseed == 25600) { randomseed = 0; } // unsigned int limit, no need to go over it.
That allows me to re-seed the rand() command, which different values, and since there's hardly a chance of someone taking the exact same number of frames in a menu or to complete a level,
it kinda makes the random seems really random.
Next step is to write a simple function to generate a random number between two values:
int rand_num(int lb, int ub) {
srand(seed); // re-seed the random number generator each time //
int ret;
ret = rand() % (ub - lb + 1) + lb;
return ret;
}
With that simple trick, i can now generate 'random levels', based on some parameters i designed, to avoid getting levels that were too easy or even worse,
impossible to complete, which is never what you want.
// Level Random //
if(level == 0) {
srand(seed); // re-seed the random number generator each time //
int r_pellet_x = 0;
int r_pellet_y = 0;
level_pellet_num = rand_num(5,20);
level_walls_num = rand_num(5,15);
en_l_y = rand_num(en_lim_top, en_lim_bot);
en_l_dir = 0;
en_r_y = rand_num(en_lim_top+10, en_lim_bot-10);
en_r_dir = 1;
level_pellet_collected = 0;
// Pellets //
for(int i = 0; i < level_pellet_num; i++ ) {
r_pellet_x = rand_num(pl_lim_left, pl_lim_right);
r_pellet_y = rand_num(pl_lim_top, pl_lim_bottom);
pellets_x_y[i][0] = r_pellet_x;
pellets_x_y[i][1] = r_pellet_y;
r_pellets_x_y[i][0] = pellets_x_y[i][0];
r_pellets_x_y[i][1] = pellets_x_y[i][1];
}
// Walls //
while(i < level_walls_num) {
w_x = rand_num(pl_lim_left, pl_lim_right);
w_y = rand_num(pl_lim_top, pl_lim_bottom);
wall_pellet_collision(w_x, w_y);
if(wall_pellet_col == 0) {
walls_x_y[i][0] = w_x;
walls_x_y[i][1] = w_y;
r_walls_x_y[i][0] = w_x;
r_walls_x_y[i][1] = w_y;
}
i++;
}
}
walls_draw();
gamestate = 1; // goto gameplay //
Its really not overly complicated, en_l_ variables set where the left turret will start, and en_r_ variables set where the right turret will start.
Then we get random numbers for how much satellites there will be on the screen (level_pellet_num) and we place that inside the playfield which is
determined by pl_lim_left, right, top and bottom, that is to avoid generating an unreachable sattelite.
Next step we generate a random number for how much wall (blocking) tiles there will be on the level.
For each new wall, we also check if its colliding with a already placed sattelite, you can't have overlap between them, to avoid generating an
'unsolvable' level, so if, and only if, there's no sattelite on that spot, we can place the wall, otherwise, we try a new random location, until
we fulfill the required number of walls.
Then we call for the routine that draws the wall tiles on the screen and move to the gameplay.
This 'random world' is imho, the best thing about the game, because the gameplay is really simple and designing a bunch of levels that are interesting enough to keep the gameplay interesting
even after the player have finished them would be above my skill level, so with the random world sequence, we can at least add a real re-playability factor to the game.
-- Part V : conclusion --
In the end of the day, Raposa do Sol was a learning experience for me, which is why i ended up adding things like SRAM and even voice samples, they
were added more for me than for the improvement of the game experience itself, because saving hi-scores on this game is not something that really
makes or break the same and the same about anyone hearing my voice very muffled saying 'raposa do sol' or 'game over, yeah" (because Sega Rally references are *tight*).
This was very fun to make and i've learned a lot, so i consider this project worth of the time i've invested into it and if anyone can also benefit from this, even better.
Which is why the code is avaiable:
github.com/jflores82/raposadosol feel free to explore it and if you have any questions
just hit the contact button, maybe you too will have fun making little games for the old Sega Master System.