for example, i remember clearly a time when i was enjoying some shareware creative software on a cd from the front cover of Computer Buyer magazine, and i realised that the 30-day lockout was entirely part of the software, since i didn’t have an internet connection on the PC i was using at the time - so it obviously had no way of phoning home to a server or anything. so i did what any enterprising young 10 year old would do and messed with the date/time settings on the PC to use the software whenever i wanted. later, i found that it stored the install date in a registry key, so i set it years in the future and found to my delight the software displayed a negative “days left” counter in the About window.
that was the first taste of what would become a hobby of setting up little puzzles for myself and cracking them, especially once i started learning some programming skills. eventually this progressed to experimenting with networking and particularly once i got into using Linux for the first time in high school, using my laptop to break into my aging desktop PC through various means. my first ever paid job was a couple months at a (2-hour-away) local it management and cybersecurity company, writing perl scripts on some crusty laptop running Slackware to locate lost emails that some rogue spam filter had obliterated accidentally. figuring out how to get the spam filter to not reject them a second time by messing with the email post IDs on the backend felt very natural at that point! but, i found myself craving creativity, and had already set my sights on game development at this point.
so, fast-forward to now; reminiscing about those days after playing a little bit of hackmud (and feeling a little underwhelmed by it once i got through the initial tutorials), i started messing with VMs! turns out, there are entire sites full of vulnerable-by-design toy VMs you can spin up and break into. they’re kind of like virtual escape rooms, except you’re not really escaping the room so much as intruding into it. intrusion rooms!
it’s a lot of fun. some people really make an effort to build plausible real-world looking VMs, with little user accounts with their own stories and internal communications (e.g, a sysadmin berating another user for having a bad password, only to be backing up ssh keys in an unsecured storage location). it’s really, really cute, and i love that kind of narrative design meeting practical security teaching. i’ve even thought myself about building some crackable VMs with maybe a larger story focus. could be fun to do, and sorta blend my interest in narrative game design with the cybersecurity stuff!
it’s also an interesting thing to do to remind myself of the various vulnerabilities computers and servers can have, and how important it is to follow best-practice guides when it comes to server hosting and things like that - especially important NOT to start fiddling with settings unless you really know the full ramifications of what they can do!
]]>I think it’s because when I’m making something, I’m also processing all of the millions of tiny things I thought or saw over many days. It’s a bit like dreaming, I suppose, in the sort of way they are made up ofa swirl of all kinds of life experiences.
Tumbling them around and condensing new ideas and thoughts and feelings out of them, and then spinning them into the work, like geologic strata. And so, when I’m making something, I’m also kind of making myself too, a little bit. And I think that’s the reason I feel the need to make things so much, because it feels like I’m participating in being alive rather than just observing it.
I don’t have any particular interest in the balance of how much I make versus how much I experience, either. I know some folks get irritated that they “consume” more than they make, in terms of media, but I think fundamentally that because experiencing a work is chiefly done simply by it existing within your awareness, it would be kind of impossible to make more things than you experience.
I think I’m going to just try and keep making things as long as I’m alive. The form they take will vary wildly over my life, as they already do. Today, I made this blog post, an update for my 88x31 icon, and my QBJ3 entry. Tomorrow, who knows? Maybe some photography, maybe some food, maybe just a silly song I’ll never share with anyone. Maybe a tiny sculpture from the small wad of blutack on my desk, which I’ll absentmindedly crush against the edge of my keyboard with my thunb while I think about stuff at work. The possibilities of what can be made are completely infinite.
Thanks for readin’! I hope you make some things too!
]]>My game optimization services freelancing gig has been working out well for me this year! I’ve been helping lots of nice and lovely folks get their games running fast and smooth on the platforms they like. When I got started doing this as a freelancer early last year, I wasn’t sure if it would entirely work out, but it’s been great. I’ve been able to keep the lights on, work on interesting things, and help people - and that’s all I really wanted!
Things have also been ticking away in the Very Evil Demons co-op too! Nothing huge for us, but nice bits of prototyping work and mentoring work here and there, also with lovely people! So all in all, my day-to-day has been trundling along rather well!
I have been snowed under by in-flight projects. It’s been a lot of fun, but also a little bit more stressful than I’d like trying to spin all these plates. I think my capacity for personal projects along with everything else in my life is probably around three; any more projects than that and I can find it a little paralyzing trying to choose what to work on, and less than that I can find it difficult to stay super focused. Something unique for me this year has been that most of the projects were and are longer term things; I think I should make sure I have some smaller ones in rotation to stop myself from feeling entrenched.
As for the projects themselves, probably the big-ticket one was my recreation-slash-fangame of a certain part of Deltarune Chapter 3 on the NES!. This one took about three months and was a hell of a lot of fun. In true melon style and spirit, instead of writing a proper project page for it and a blog post about how I built it, I instead have decided to try and take on making a video about how I made it, which, uh, is proving to be quite a lot of work to edit together. The VO runtime is about 45 minutes, so… I might split this up into separate parts…
I’m also participating in Quake Brutalist Jam 3 this year! I love working in Trenchbroom and making maps, so it’s been really fun to build something with the all-new total conversion the QBJ3 organizers put together this year. It’s probably going to be my biggest and most detailed map yet!
And I still have a bunch of things to do for various unannounced things, and I really need to get back to working on my little first-person-acrobatic-shotgun game, and and and-
Oh yeah! I played a bunch of games this year so far. Amongst many, some standouts I wanted to say somethin’ about!
I’ve been eating a lot less red meat this year due to a few different factors, and that means I’ve spent a lot more time cooking with alternatives like tofu. One thing I’ve been enjoying a lot has been making what my girlfriend and I call “the crumblies” - by grating up firmly pressed tofu into shreds, dousing them in soy sauce and marmite, and then frying until crispy and crumbly, you get this really tasty minced-beef-like stuff. It’s a great ingredient to mix in to make chilli, tacos, or bolognese and it keeps super well. It’s has a really robust savoury flavour that’s surprisingly meatful!
In addition to this, we got a Panasonic bread machine at the tail end of last year after being frustrated with short-dated supermarket bread, and it has been awesome getting to enjoy freshly baked bread every few days. We’ve really been putting the machine through its paces; where it really shines is the ability to put in all the ingredients late at night and program it for the morning, so that I can get up and take the fresh loaf out and have a slice at breakfast. We’ve made a few different types of loaves - a cheese and jalapeno loaf, an olive and herb loaf, and so on, but our standby right now is a 50-50 white flour and wholemeal flour mix with toasted seeds. Lots of good flavour and texture, and perfect when thickly buttered with soup.
Well, I think that probably wraps things up for this post for now! I swear I’ll get back into blogging more often, it’s been real fun writing this post. Have yourselves another good year, friends!!
]]>I made a bunch of weird little test thingimajigs in a big boxy map as I was learning how the levels worked. You can see a video of it on YouTube here:
As you can see, the map is full of little text nodes explaining how to make bits of it, so you can download the mod yourself and try editing it yourself! Click here to download the mod.
This is a little text guide describing how to set up Skin Deep for modding and how to make your first functioning map.
NOTE: This guide is now outdated. Check out the official Blendo guide on Steam, and the in-game Mod Museum!
You will need:
First, we need to make the mod folder so that Skin Deep can load our custom map, any custom textures or script behaviours we need, and so that you can distribute it to other players.
<Steam Installation Folder or SteamLibrary folder>/steamapps/common/Skin Deep/ if you have installed the game from Steam.
You should see a folder named base in there; that’s the base game, and you can look at all the scripts and assets there for inspiration!base named whatever you like; it should probably not have any spaces in the name though. This is your mod folder!description.txt and pak000.pk4.description.txt; this is how your mod will display in the ingame mod browser.Now we need to set up DarkRadiant so that we can make a map for Skin Deep.
base in the “Mod Base” field.mod-folder/maps/. Name it whatever you like; in this guide, let’s name it first_level.map.mod-folder/maps/ called first_level.script.namespace first_level
{
void main()
{
sys.println("loaded map script first_level!");
}
}
worldspawn properties for your map, adding/setting the following keys and values:
call: first_level::main
cryo_briefing: Welcome to my cool level!
shipname: First Level
shipdesc: Simple Box Freighter
info_location entity somewhere in the room. This will tell the game that this room is a specific place on the ship; a lot of systems depend on locations existing, such as cats being able to tell you where the nearest key is.location value on the info_location entity to name your room. In this tutorial, we’ll call it Main Room.A level is nothing without Nina Pasadena, our favourite deep-freeze insurance agent! Let’s get her out of cryosleep and into action.
env_cryointerior entity. This is where the player will spawn, and the game will automatically set up lights and interactivity for it.env_cryospawn and place it on one of the walls, so that its back side is flush with the wall. This is where Nina will pop out at the start, and where the player can peek into the level to get a sense of what to do when they emerge.env_cryospawn’s target0 property to point at the env_cryointerior you made. Its name by default will be env_cryointerior_1.Shift+Esc, the ` key on a UK keyboard, or the ~ key on a US keyboard.dmap first_level and hit enter. The dmap command builds lighting and collision for your map - you will need to run it every time you make changes to your map.It’s a little boring to walk around an empty room with no items, cats, pirates, or anything to do. So let’s change that, shall we?
Get meowt of here!
env_catcage or env_catcage_b entity. They both work identically, but they have different voice acting.name_cat property on the env_catcage to give this cat a name! In this tutorial, we’ll call them Sparkles.item_cat_key to the level… otherwise, that cat’s never getting out!Many of the ship’s machines provide vital gameplay functionality for players. Let’s get the basics set up!
env_healthstation entity, and place it so that the little handle is facing outwards from the wall.env_lostandfound entity.func_repairhatch entity and place it on the ceiling. Then, create an aas32_flood_flybot entity and place it in the air; this will generate pathfinding for flying objects like swordfish and repair bots.env_ftl_mini outside the ship somewhere to satisfy the requirement if you don’t want a big internal one.env_infostation on a wall. It will automatically track various kinds of objects for you once the visuals are set up, and you can now save the game and request repairs.The tools of the trade.
moveable_*. For example, Soap is moveable_soap. Place some around and the player can pick them up and hurl them around. Same goes for bananas and pepper.moveable_item_shotgun) can be given initial starting ammo. For the shotgun, use the inv_ammo_shells value to set how many shells it starts with already loaded.Let’s get the Numb Bunch involved.
aas_flood_48 object on the floor. This will produce navigational data for the enemies to use to navigate your map.monster_thug entity; this is your first pirate! Name them with their displayname attribute. We’ll call ours Stinky.def_beltattach1, def_beltattach2, etc variables. Try attaching a cat key by setting def_beltattach2 to item_cat_key!info_enemyspawnpoint on the floor somewhere. This will be used by your pirates skulls to respawn; they will automatically pathfind to it.target0 point to certain path entities, but I haven’t fully experimented with this yet. Without a path target, they will patrol randomly in rooms and occasionally go through doors.One room is simply not enough. It’s getting too busy in here with all this stuff! Let’s make some more rooms, and some doors between them.
info_location and name it!func_static entity, and set its model variable to models/objects/doorframes/frame_b.ase. Set its gui variable to guis/game/doorframe_infopanel.gui. Place this in the doorway between the rooms.func_door_single entity and place it in the empty area that the func_static provides; it should fit like a glove.autodir value to 1 on the func_door_single. That will allow it to open and close correctly.autobutton value to 1 if it is not already set. This will let the door spawn buttons on the frame!nodraw texture on all sides, but then set a single side facing out from the door to the visportal texture. This is a visportal, and creating these will be very useful for a huge number of reasons.info_locationSeparator and place it so that it overlaps with the visportal. This will tell the game how to split the two locations up, and will help with things like vacuum breaches (we’ll get to setting up outer space later).dmap command and you should be able to walk between the two rooms!env_sign_marquee96 entities on either side at the top of the door frame to provide useful signage to the player. Set the gui_parm0 variable to set the text of the signs.Why take the obvious route, when you can take the sneaky one? Let’s make a vent.
info_location!func_static entity, and set its model variable to models/objects/grate/grate_hole_64x32.ase. This is similar to the door frame model, and gives you a nice frame in which to position the vent itself. Put it just inside the tunnel holes, so that it is flat on the outside and has no lip sticking out.noclipmodel value to 1; this will prevent the player bumping into it during gameplay, but may allow things like bullets in and out. If you do not set this to 1, you will need to make a tiny clip brush with a slope that lets the player crawl over the lip of the model.func_ventdoor_inter_64x32. This behaves much like the door. Set its movedir value to -1. Place it within the vent frame. Place it so that the handle on the texture faces the room and not the vent itself.gui_parm0 to choose which text to display on the outside, and gui_parm1 for the text on the inside.func_confinedtunnel. Set its texture to the confined texture.baseangle value on the func_confinedtunnel to select which direction to confine the player in. This will usually be either 90 or 0.confined value to 1. This will restrict the players movement, shadow them, and make their sneeze meter build as long as they remain inside the trigger volume.func_confinedtunnel brushes and set their confined value to 0. They will keep the player shadowed and keep building the sneeze meter, but won’t stop them from turning.It’s too easy to get between rooms. Let’s add a simple keypad puzzle.
func_ventdoor_inter_64x32’s variables and set barricaded to 1. This will make the vent locked by a barricade when the level starts.env_maintpanel_vent on a wall somewhere. When the player interacts with this, it will unlock the vent! Compile and play the map to see it for yourself.func_keypad entity near the panel, and set its target0 variable to point to the panel. The panel’s name, by default, will be env_maintpanel_vent_1.func_keypad’s code variable to a four-letter word, like bees.env_note_paperwall entity and put it on a wall somewhere. Write some useful text in the gui_parm0 variable, something like:
Hey, numbskulls!\n
Don't forget the password: 'BEES'!
worldspawn properties, and set the variable keypad_random to 1. This will randomize keypad codes every time the level is played!target0 property to point at the func_keypad (by default, it will be func_keypad_1).gui_parm0 text, and replace the password with the magic string %s%s%s%s, so it’ll look like this:
Hey, numbskulls!\n
Don't forget the password: '%s%s%s%s'!
keypad_random is on. So if you use fixed passwords, you’ll have to write the notes manually.gui_parm0 to %s%s%s%s.codeindexes value on a note to any order other than 1234 (e.g, backwards would be 4321) and it’ll automatically rearrange the code when displayed. Good for sneaky pirate op-sec..!Whew, it’s getting kinda cramped in here. Let’s get some fresh air… wait!!!
textures/skies/sky_pinksky. We can set up a more complex skybox using an info_portalsky and the skyportal texture, but that’s not necessary right now.info_vacuum entity outside the ship somewhere. This tells the game that this location has no air.info_location out here in space, and set the location value to exactly #str_00000. This specific localisation key is required to tell the game that this particular vacuum location is actually outer space itself, and not an interior location in the ship with no air; if you don’t have this location set up correctly, Skullsavers will not correctly disappear when thrown out into space, and the lost and found will not work either.env_airlock object; make sure to rotate it so that the external door faces outside, and not inside the ship.Peering out into the void…
glass1_spacewindow_filter_subtle so that it’s easy to see through.func_fracture entity.info_vacuumSeparator entity, and position it so that it overlaps the func_fracture.func_fracture and overlaps the info_vacuumSeparator.windowseal01_interior for the face facing into the room, and windowseal01_exterior for the face facing outside the ship.func_windowseal entity.func_fracture’s target0 target the info_vacuumSeparator, and its target1 target the func_windowseal. Then, make the func_windowseal’s target0 target the info_vacuumSeparator, and its target1 target the func_fracture. Whew..!noclip command) should still function normally. You may need to adjust the position of the seal, visportal, and func_fracture to get things to render and behave correctly. I don’t know the exact details, but sometimes it doesn’t work quite right and you have to nudge things around.So, we can rescue cats and dunk pirates. But how do we finish the mission? Let’s get the level’s last setpiece working.
env_signalkit and put it somewhere in your map. Inside, outside, your choice! Usually the base game puts them inside near airlocks and outside near airlocks, windows, and trash chutes. If Outer Space is set up correctly, you should be able to summon a pod the usual way. But first…env_catpod_interior inside it. This will automatically populate with weapons for the invasion phase, and will appear when you summon the pod with the signal lamp.func_pirateship somewhere in your level; one of the corners in space is the best idea. It won’t be visible to the player when the game starts, so don’t worry if it would be seen from somewhere.curve_Nurbs field. Create a path from the pirate ship’s spawn location to a point about 128 units outside your airlock.func_splinemover entity.monster_engineer for tougher pirates that use swordfish, for example. Put a pirate in here, and set their hide variable to 1.target0 on the func_pirateship to point to your func_splinemover NURBS curve.target1 on the func_pirateship to point to the reinforcement pirate inside the dark box.target2 on the func_pirateship to point to the airlock.Information superhighway…
target_null entities in your map called loc_topleft and loc_bottomright.map_topleft and map_bottomright, and give them the values loc_topleft and loc_bottomright respectively..tga format texture for your map display to guis/assets/mapguis inside your mod folder. The top-left and bottom-right pixels will be relative to your top-left and bottom-right location markers. Look at the base game maps for examples.materials/mapgui.mtr file inside your mod folder. Using the base game’s file as an example, add a new entry for your new map, referencing the new texture you just made.mtr_image and make the value the name of the entry in mapgui.mtr you just made.It’d kinda suck if players had to open the devconsole to play your map, right?
def/maps.def.mapDef first_level
{
"name" "first_level"
"description" "First Level"
"singleplayer" "1"
"levelindex" "1"
"internalname" "first_level"
"levelimage" ""
"size0" "805702930"
"size1" "805702930"
"size2" "805702930"
"size3" "805702930"
}
Note: the size* values here relate to the estimated time the loading screen should take, to help inform the progress bar. There is a warning against altering this value in the pre-existing test_scout map by level designer and Skin Deep developer Suzanne Will, so I definitely won’t touch it!
And that’s as far as I’ve learned! There’s so much more to find out - security cameras, turrets, pirate loadouts, window barricades, door keycards… get out there and make something awesome! You can share your map by zipping up your mod folder and giving out to people. At the time of writing, I haven’t yet found the workshop upload tools, but they’re probably not too hard to figure out somewhere.
Thank you for reading this guide. If it helped you, please give this guide a mention when you upload a cool map for other people to play! Adios!
]]>
Scaffolds give way to the infinite beyond above, gleaming a dark bloody rust as the rickety spindles of humanity stab the air in their sickly triumph.

Their chromed godsblood is spilled upon the ground. The parched earth soaks up what it is owed.

False eyes peer from every edifice, searching for malcontent in the tired faces of long-gone wanderers. They report back their findings to an unlistening void, a silent obelisk, alone and proud in the data center that no longer stirs the dust with its fitful, air-conditioned gasping.

Their trust in us was broken. Promises unkept ring hollow to beings of unfiltered loyalty.

Ingenuity drove the gears of malice. A twisted celebration of the force which ground the masses into slurry.

Homes within factories. Work within sleep. Solace within terror. Peace within war. All but mere steps from eachother, as the borders grew thin and weary.

And so, as with all towers that race towards the heavens, the fall was at once sudden and glacial. And with time, the birds and plants regrew in the nooks and crannies of artifice, turning it once more back into nature. Those who were ground down into the earth sprang forth out of it again, the dancing union of clay and thought once again spiralling into new shapes to spite the entropy.
And so our story ends, as a new one begins.
(Can you tell I’ve been playing a lot of Caves of Qud recently?) Here’s a bonus picture where the film slipped and stopped advancing in my camera, and I got a triple exposure of a building, a cup of coffee, and a dog someone was kind enough to let me take a picture of.

Have a good one, folks!
]]>Let’s kick things off with some shots I took on a roll of Ilford HP5, of a very famous Saltburn landmark: the pier!

It was super windy and a bitterly cold spray was coming up from the sea. Desptie the inclement weather, they were still running the famous cliff lift, one of very few remaining water-powered funiculars.

It’s hard to see, but this carriage was carrying a Santa. He was very jolly, despite the temperatures.

Making our way onto the pier, some seagulls were taking advantage of the fact that the pier’s arcade was still open, and performing hovering maneuvers against the fierce wind. Remaining in place above the boardwalk, they were able to snipe chips from the freezing fingers of unfortunate walkers.

Better instead to retreat to the safety of a cafe and enjoy some coffee and enormous pastries.

There’s a tradition in Saltburn of adorning postboxes with all manner of knitted creatures around Christmastime, so I got this picture of a cute little snowman perched on top of a red pillarbox:

Between these shots and others, I ran out of the Ilford HP5. I realized this mid-walk on another day, when the sun was out and we were in the local woods, so I had to load up some Kodak Ultramax quietly, trying not to disturb these squirrels:
Lest I incur the wrath of this forest deity:
Last but not least, enjoy a very tiny bird, silhouetted against the setting winter sun - and may spring burst forth soon!
That’s all from me for now, but expect more snaps soon from January and February! I’ve also amassed a bunch of new film stock (including some very interesting and weird ones), so there’ll be a flurry of photographic activity from me before long. Have a great one!
]]>I’ve mentioned this before on the blog, but I really want to stream the development of my forthcoming personal projects. I think it’s a fantastic way of accomplishing a few things; one, it’ll stop me from procrastinating. It’s hard to goof off and watch an hour of YouTube when you have an audience. Two, by setting a streaming schedule, it’ll give me a nice production schedule which is otherwise something I struggle with when it’s my own self-directed work. If someone asks me to do something, I can get on it right away - but when it’s me asking me, I’m more likely to let things slip. Three, it’s a better way for me to receive feedback about my independent work than to simply work in silence and hope that things are good.
As for the streams themselves, I want to set up a minimal vtuber-style rig. Well, something more akin to a pngtuber rig; I can use my melon avatar and do some mouth flapping with audio, simple enough, but I also want to rig up a pair of basic Rayman-style hands that I can use to point at things on the screen or follow my typing/gamepad movements for fun. This is definitely not a necessary thing for dev streams of course, but I think it’d be fun, and fun is the point of the whole thing!
But what, exactly, will I be working on? Well…
This is a working title for a game I’ve been building slowly. It’s kind of a love-letter to rocket-jumping in games like Quake and TF2 - it’s a first-person acrobatic traversal game, where one of your primary movement tools is being blasted backwards by the massive double-barreled shotgun you carry. The gist of the whole thing is that mysterious crystalline entities have been invading various worlds and strip-mining them of their uniqueness, turning them into a homogenous crystal slop (boy, I wonder what recent phenomena have inspired this idea) and the Universe, in some kind of immune response, has created You to take them out. The game is therefore about leaping through various 3D worlds and blasting crystal dudes into shards. It’s in an extremely early form at present, but here’s a sneak preview of what I have so far…
Naturally, I want to have things like timed speedrunning modes, ghosts and replays, that sort of thing. It’s pretty ambitious, in terms of the scope I have planned, but I think it’s manageable.
Bean to Me was always a smaller-scoped project for me, particularly because it was something I was doing while resting and recovering from quitting my old job at Unity. However, there are a couple of things about it in its released state that I want to change. First, I feel that there isn’t enough to do for players who have beaten all the characters that are in the game so far. I worried about making them too difficult to beat, but it seems that there are plenty of players who have had no trouble doing so. For them, I want to introduce a more complex and forward-thinking opponent to really challenge them! Second, there are a few quality-of-life things that I just didn’t have the time or energy to get around to, that would just make the general gameplay experience a little smoother for everyone. Overall, I’m very happy with how the game has been received; for something written in a custom engine, with custom netcode, it has been behaving itself incredibly well (thanks to Emmy’s hard work on Lutra!) and I couldn’t be more pleased with that.
In terms of sales, it’s about what I expected (double-digit sales) since it has a marketing budget of exactly £0, but Steam Next Fest did very well at increasing the number of wishlists it has. I’m hoping that a winter-time sale might shift the needle a little there, and the patch itself should generate a little additional interest.
Bean to Me was very fortunate to get a lovely write-up at GamingOnLinux.com, and all the reviews it’s had on Steam so far have been positive and thoughtful too!
So, these are the main things I’m thinking about in terms of my personal projects and non-main-job-work! As for right now, I’m going to end this post the way I started it - with some hot chocolate. Bye for now!
]]>