2016 Shakedown
Another year is behind us and I am here once again posting a summary of what I’ve been hacking on in my spare time, which translates to evenings and weekends.
This year was more of a year of ideas when it comes to my personal projects. I did not release a great many things, but fiddled with various ideas and crystallized the road ahead.
To put things into perspective, here are some charts generated by GitHub.
2016 vs 2015
Menhir
Menhir is a simple puzzle game, the player’s sole purpose is to try to clear the board by utilizing empty spots.
This is modeled after a “board game”, I really enjoyed in my childhood.
Special thanks go out to Kenney “Asset” Jesus for the sprites.
If you want to try it out, you can do so by clicking here.
Fz2D
Fz2D received a couple of more updates, and slowly but surely getting closer to graduating from alpha into beta.
I’d like to add / wrap-up the following things next year:
- Fz2D.Camera (scrolling, etc)
- Built-in asset pipeline (texture and font atlas generation)
- Improved (painless) handling of dependencies
Feel free to take a peek at the documentation available over here.
nyan.c
This was a warm-up for IOCCC, but then it turned out that there was no competition held this year. Oh well ….
#include <stdio.h>
#include <unistd.h>
int main(){const char *O_o[]=/*msz*/{
" ,------,\n" "v| /\\__/\\ \n"
" |__( ^ w ^) \n" " \" \"\n",
" ,------,\n"
"~| /\\__/\\\n"
" |___( ^ w ^) \n"
" \" \"\n",
" ,------,\n" "^| /\\__/\\\n"
" |___( ^ w ^) \n" " \" \"\n" };
int i=1;for(;;){printf("%s\x1b[4A",
O_o[(i=(i+1)%3)]);usleep(200000);}}
ZeeCraft
Added an HD mode to my ZeeCraft project.
Special thanks, once again go out to Kenney “Asset” Jesus for the textures.
fastopen.vim
I made a few updates to fastopen.vim. A quick “file opener” for vim using “dmenu”.
JSIP
JSIP can pack a piece of JS into a plain PNG image. Does not rely on any custom chunks or other exploits.
input: helloworld.js
alert('hello world');
output: helloworld.html
<html>
<head>
<title>Helloworld</title>
</head>
<body>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAAAAAAUMi+rAAAAIUlEQVR42mNI
zEktKtFQz0jNyclXKM8vyklR17RWGDkAAJWCJK98ao+pAAAAAElFTkSuQmCC
"
style="visibility: hidden; position: absolute; top: 0; left: 0;"
onload="this.remove(); var c=document.createElement('canvas').getContext('2d'); c.canvas.width=this.width; c.canvas.height=this.height; c.drawImage(this,0,0); var p=c.getImageData(0,0,this.width,this.height).data; var s='';for(var i=0;i<p.length;i+=4)s+=String.fromCharCode(p[i]); (1,eval)(s);" onerror="this.remove();" />
</body>
</html>
Even with the indirect eval, the resulting code is slower than the same code included and executed directly; but it was a fun thing to experiment with, nonetheless.
To view a non-interactive visual demo produced by JSIP, click here.
Noty
Noty is a small note taking application, I written in pure bash script. It’s roughly 200 lines long, including comments and stores notes in GFM.
It is possible to store all notes in a user specified location by exporting the NOTY_DB
variable
in your .bashrc
like so:
export NOTY_DB=$HOME/Dropbox/.noty
The command line interface is really simple.
Noty v1.0.0
usage: noty command [arg] [note]
commands:
c - create a new note
l - list notes
m - mark a note
u - unmark a note
A little example is in order to demonstrate how lean and mean it is to use.
~ $ noty c 'hello world'
Initialized 'testdb' ...
Initialized '2016-12-30' ...
Added note 'hello world' ...
~ $ noty l
2016-12-30
----------
1. [ ] hello world
~ $ noty c 'make cake'
Added note 'make cake' ...
~ $ noty m 1
Marked note '1' ...
~ $ noty l
2016-12-30
----------
1. [x] hello world
2. [ ] make cake
#!/bin/bash
#
# MIT LICENSE
#
# Copyright (c) 2016, Mihail Szabolcs
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the 'Software'), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
NOTY_VERSION='1.0.0'
if [[ -z "$NOTY_DB" ]]; then
NOTY_DB="$HOME/.noty"
fi
function get_current_date()
{
date +'%Y-%m-%d'
}
function preg_replace()
{
sed -i -e "s/$1/$2/" $3
}
function preg_remove()
{
sed -i -e "/$1/d" $2
}
function db_init()
{
if [[ ! -f $NOTY_DB ]]; then
echo -e "Noty v$NOTY_VERSION\n===========" >> $NOTY_DB
echo -e "You have a total of 0 notes." >> $NOTY_DB
echo "Initialized '$NOTY_DB' ..."
fi
}
function db_get_id()
{
local OLD_ID=$(grep -m 1 -P '^You have a total of \d+ notes.$' $NOTY_DB | cut -d ' ' -f 6)
local NEW_ID=$((OLD_ID + 1))
preg_replace "^You have a total of $OLD_ID notes.$" "You have a total of $NEW_ID notes." $NOTY_DB
echo $NEW_ID
}
function db_write_note()
{
db_init
if [[ -z $(grep "^$(get_current_date)" $NOTY_DB) ]]; then
echo -e "\n$(get_current_date)\n----------" >> $NOTY_DB
echo "Initialized '$(get_current_date)' ..."
fi
echo "$(db_get_id). [ ] $@" >> $NOTY_DB
echo "Added note '$@' ..."
}
function db_delete_note()
{
preg_remove "^$1. \[ \]" $NOTY_DB
echo "Deleted note '$1' ..."
}
function db_get_notes()
{
if [[ "$1" == "all" ]]; then
cat ${NOTY_DB}
else
local LINE=$(grep -m 1 -n -P "^$1" $NOTY_DB | cut -d ':' -f 1)
if [[ -n "$LINE" ]] ; then
tail -n +$LINE $NOTY_DB
fi
fi
}
function db_mark_note()
{
preg_replace "^$1. \[ \]" "$1. \[x\]" $NOTY_DB
echo "Marked note '$1' ..."
}
function db_unmark_note()
{
preg_replace "^$1. \[x\]" "$1. \[ \]" $NOTY_DB
echo "Un-Marked note '$1' ..."
}
function command_c()
{
if [[ -z "$1" ]]; then
echo "You must provide a valid note."
exit -1
else
db_write_note "$@"
fi
}
function command_d()
{
if [[ -z "$1" ]]; then
echo "You must provide a valid note id"
exit -1
else
db_delete_note "$1"
fi
}
function command_l()
{
if [[ -z "$1" ]]; then
db_get_notes $(get_current_date)
else
db_get_notes "$1"
fi
}
function command_m()
{
if [[ -z "$1" ]]; then
echo "You must provide a valid note id"
exit -1
else
db_mark_note "$1"
fi
}
function command_u()
{
if [[ -z "$1" ]]; then
echo "You must provide a valid note id"
exit -1
else
db_unmark_note "$1"
fi
}
function help()
{
echo "Noty v$NOTY_VERSION"
echo -e "\nusage: $(basename $0) command [arg] [note]"
echo -e "\ncommands:"
echo -e "\tc - create a new note"
echo -e "\tl - list notes"
echo -e "\tm - mark a note"
echo -e "\tu - unmark a note"
exit -1
}
function main()
{
local CMD="$1"
shift
local FUNCTION_TYPE=$(type -t "command_${CMD}")
if [ "$FUNCTION_TYPE" == "function" ]; then
command_${CMD} "$@"
else
help
fi
}
main "$@"
SteamSpy
If you like to spy on Steam games a lot like I do, then you might find the bookmarklet or the TamperMonkey script below very very useful.
Bookmarklet
Open SteamSpy on any Steam store page with a single click.
javascript:window.open(window.location.href.replace('store.steampowered', 'steamspy'))
TamperMonkey Script
This script adds a SteamSpy button to every Steam store page.
// ==UserScript==
// @name SteamSpy
// @namespace http://mihail.co
// @version 0.1
// @description Adds a Steam Spy button to every Steam store page.
// @author Mihail Szabolcs
// @match http://store.steampowered.com/app/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
var el = document.querySelector('.apphub_OtherSiteInfo');
if(!el) return;
var a = el.querySelector('a');
if(!a) return;
var newa = a.cloneNode(true);
newa.href = 'javascript: window.open("https://steamspy.com' + a.href.match(/\/app\/([0-9]+)/)[0] + '");';
var text = newa.querySelector('span');
if(!text) return;
text.innerHTML = 'Steam Spy';
el.appendChild(newa);
})();
Hamunaputra
Hamunaputra started as a 32KB room-based roguelite for DOS, written in plain 16-bit ASM, with everything being packed into a single .COM executable. No external files, or dependencies of any kind.
Never finished it, and currently sits in the back burner.
Nexeh & Nixel
This has been my primary focus this year, and will continue to be next year. Like I mentioned before, I would like to build and old-school first person shooter, retaining as many original elements as possible, while at the same time throwing a couple of new twists into the mix for good measure.
My definition of old-school includes (but not limited to), games like:
- DOOM
- Hexen and Heretic
- Duke Nukem 3D
- Painkiller
- Shadow Warrior
I want to go for the 2.5D look, with 3D world geometry and 2D sprite based (billboard) entities. Haven’t settled for a general look and feel yet, because I am still working on some of the core tech.
… with some sprites ripped from Hexen …
… and compiled with emscripten …
I managed to figure out most of the architectural questions; will try to blog about some of the technical stuff in the weeks to come. Stay tuned.
Like I promised, it’s all going to be open source when it comes to the code and tech. When am I going to open source it? Well, that remains to be seen, but most likely only after I have something more or less playable in my hands.
Greed
Stumbled upon In Pursuit of Greed and decided to modernize and port it, keeping the original software renderer intact, while allowing for higher resolutions, both upscaled (from 320x200) and native.
Here you can see a screenshot of the game running at whopping 800x600 resolution.
This is still very much work in progress, and I work on it every once in a while, but we’ll get there sooner or later.
Writings
There is plenty of literature when it comes to game development, but none of it is focusing on the actual so called practical side of things. There are bits scattered here and there, but nothing exhaustive or conclusive.
Most of the books, just rehash and regurgitate the very same things, perhaps updated or modernized in places, but still presented in rather outdated formats.
To change the status quo, I started sketching out three books, Software Rendering for the practical game developer, Game programming for the practical game developer and a companion guide entitled, Mathematics for the practical game developer.
I want to focus purely on the practical side of things, avoid platitudes and urban myths, however, when any of these will turn into actual paper that one can hold in their hands, one again, it remains to be seen …
On a different note, there’s still considerable interest in my FloppyBird project, which means that it’s time for me to write a Making of Floppy Bird, sometime next year …
Pyramid Hologram
Before I even get started, yes, yes, yes, it’s not a real hologram, but it’s still 10x more interesting than the idiotic thing we call VR. Who on Earth wants to stick half a kilogram of equipment on their head? Apparently quite a few. Good luck with destroying your eyesight faster than a good old CRT would.
Now that we have that settled, let me dive into the details.
The so called “DYI holograms” have been circulating on the Internets for quite some time, but all efforts seem to be focused on displaying animations, instead of real-time applications, like video games.
Basically, you build a pyramid and then you use a tablet or another device to project on it by placing it on the top, you can see this in action in the video above.
(Source: ~mhsung)
In order to achieve the effect, one has to prepare a special video, which you can see below.
What’s really going on here? The answer is really simple. It’s the same thing rendered from 4 different angles, which is then reflected on the 4 sides of the pyramid, giving the illusion of a volumetric hologram.
Do you see where this is going? When it comes to games, all one has to do is render in real time the visible scene from 4 different angles, by rotating the so called camera.
Isn’t that expensive, to render almost the same thing 4 times? Well, it really depends on a couple of things like: complexity of the scene, output resolution and overall graphical fidelity.
I want to build a prototype with something relatively simple, like Tux Racer. Take a look at the small sketch I made to illustrate the concept, in order to put things into perspective.
In many respects this is similar to split screen local couch co-op, where the screen is split into 2 to 4 individual viewports giving each player the ability to roam around freely.
Left 4 Dead 2
Super Mario Kart
Imagine sitting at a table and each player seeing the very same world from a different view. Wouldn’t that be super duper cool? I’ll let you decide …
Rover
Even though Elon Musk is very very optimistic when it comes to colonizing Mars, and yes he is definitely going to democratize the rocket business, but we are very very far away from man setting foot on Mars.
NASA got their rover moving around, snapping a few photos here and there, but every time something interesting pops-up on one of those photos, they always seem to be very eager to discredit it or just blatantly ignore it.
I fully understand, you can’t just move around a few billion dollars worth of machinery, willy nilly, as you please. I get that 100%, but when there’s considerable doubt when it comes to certain geological features that appear to resemble man-made structures or statues, the silence and the same old same charade becomes quite annoying.
Nobody is saying that every rock formation that looks suspicious is a statue or some relic left there by some ancient civilization, but all it would take is to move closer to one instance and take a closer photo. That’s all it would take, and then all the crazy conspiracy theorists would just shut up and crawl back into the caves they emerged from.
I’ve been thinking about this, what if, we could create an inexpesive machine which could roam around freely, with its sole purpose being taking high resolution close-up photographs of certain points of interests.
A few details about the sketch above:
- in terms of scale, it should be the size of a regular sitting ball
- the outer shell rotates around the inner shell
- the inner shell is always axis aligned, regardless of the outer shell
- 3 solar panels, which means that two of them will receive sunlight regardless of the rotation of the outer shell
- the inner shell contains a black-box with all the equipment (camera, comm-link, a mini PC, etc)
- the outer shell should absorb any shock (i.e when landing)
I am pretty sure that there are many things that I didn’t think of, or things that are just plain wrong or impossible with such a design, but the general idea would be to build a dozen of these and then let them loose on the surface or Mars. Each of these could visit a place of interest and send back high resolution photographs.
Since it wouldn’t contain any expensive scientific equipment the building costs should be minimal, compared the rovers that have been deployed in the past.
SketchFab
A couple of my favorite sketchfabs.
End
Phew, if you managed reach THE END, you are as brave as you are foolish. All in all, it has been an interesting year, like I mentioned above, my main focus for 2017 is going to be my old school first person shooter project. It would be nice to reach some sort of a playable tech-demo state, sooner rather than later.
Since I am not a console gamer, my new years resolutions cannot be as simple as 720p, I hope that you can understand that. (PC MASTER RACE FOR LIFE REPRESENT)
Oh, I almost forgot, mostly because I’ve been rambling for so long, my game of the year, IS most definitely, without a shadow of a doubt, silence and drum rolls, Firewatch.
To view all the photos I took in-game, click here.
Jane Ng and the rest of the team did an amazing job when it comes to crafting the world of Firewatch.
Until next time, as server said, END OF LINE.
2016-12-31