Paint Tool Impressions

Since my last entry, in which I found myself at a development crossroads, I’ve taken some time to explore different paint tools. For Horde Rush and parts of Number Crunchers, Adobe Photoshop Elements 9 (PSE9) and Paint.NET were my tools of choice, because I was most familiar with them, and I already had a license for PSE9. When you’re a starting indie developer, you typically need to go with what you know rather than spend hours or days trying to learn something. That said, I’m not a fan of the results I generated, overall. It simply got the job done. And when I look at some AAA art from games like Warcraft (or anything from Blizzard for that matter), indie art like Bastion, Pinstripe, and Cuphead, and basically, ANYTHING on ArtStation, I can’t help but feel like I’m missing something; well, besides my lack of practice and experience in the last decade or so.

With some of the tools I mention here, I went through the entire process, from sketches, inks, to paint and background, using the hero character in Horde Rush as the subject. Unlike other review articles, I spent the most time with the tools that continued to vibe with me, and only spent as much time as I wanted with the other tools until I was unsatisfied with the experience. So yeah, not objective at all. These are pretty much my early impressions, and nothing more.

Photoshop Elements 2018

I’ll be honest. The only reason why I jumped onto PSE2018 (and this entire research project for that matter!) is because Adobe had it on sale. Since I’m using an old version of PSE, I decided I’ll update to the latest version for a fraction of the original price.

In all fairness, of the tools I’m comparing, PSE is definitely a photo editing tool, and not really meant to be a paint tool. Regardless, I’ve used it as my primary paint tool throughout Horde Rush development. As such, it will continue to be my all-in-one graphics tool, but not necessarily my favorite. Also, it is in the same price range as the other tools, so that’s the reason I have it in consideration here.

I’ve never really been completely happy with the results I got out of PSE. But with PS being the industry leader, blah blah blah, I have stuck with the brand. Well, it’s lighter, less powerful version, at least. I used to play around with an old copy of Photoshop 6.0, before Elements was a thing, so I’m fairly comfortable with the user experience. I get by with doing game development artwork with PSE, yet I still miss the pen tools in PS. On top of that, I’ve never been too knowledgeable about Photoshop’s plethora of brushes, so I’ve only really stuck with the basic tools.

Once I fired up PSE2018, I was immediately reminded that this program is for the novice-intermediate photographers, scrapbookers, and other such hobbyists. The interface is significantly more basic than previous iterations. But at least it’s clean. PSE2018 still has that annoying eLive/Quick/Guided/Expert menu bar that occupies valuable vertical real estate, and I doubt Adobe is planning to make this collapsable or movable any time soon. The first thing I did was click on the “Expert” link at the top, and my mind was eased a little bit, as I got back a number of controls and menus. As I started painting with my Wacom tablet, I noticed immediate unresponsiveness. Fantastic! Just what I’d expect from Adobe! Sarcasm aside, I knew that I had to go through all the Windows 10 Pen and Tablet and Touch settings, to try and disable that insidious circle icon that appears whenever you start drawing. Just remember to disable Windows Ink anywhere you can. There’s a setting in the Wacom Tablet Control Panel for this as well. It was a bit frustrating because I have been using PSE9 on the same machine without any issues, and I had to go back into my tablet settings to fix the issues for PSE2018. After that, I felt a lot more at home with PSE2018.

Photoshop Elements 9. From upper left to lower right: sketch, ink over sketch, ink, paint, ink over paint, ink over paint on background

So, I didn’t draw/paint the above image with PSE2018. That was in PSE9. Turns out that PSE2018’s brush tool isn’t using the Wacom tablet’s sensitivity settings. After doing some Google searching, it turns out that this is a big issue with Photoshop/Elements users. Toggling the Wacom Windows Ink setting helped some people, and for others, like me, it did not. I spent hours fiddling around with trying to get it to work. There should be no reason why PSE2018 is the ONLY paint program installed on my machine that does NOT use pressure sensitivity. I had just bought it… PSE2018 was a big fail for me, so I’m sticking with PSE9, since I didn’t observe any advancement in PSE2018, and I’ve requested a refund from Adobe.

SAI Paint Tool

This tool blew my mind. I never heard of it until I did some searches and watched on youtube some of the incredible artwork that was getting generated.

I’m still on the 30 day trial, but the asking price of about 50 bucks (converted from Japanese yen) is quite reasonable. At first glance, the interface is antiquated, in a “Windows 98” sort of way, but very efficient and functional. Everything you need is where it should be, or where you can easily find it. The installation process is also pretty outdated, as it doesn’t get installed in the typical Program Files directory, and probably doesn’t even use the /Users directory. But sometimes, the old file structure is a good thing, because it’s certainly more up front to the user. You don’t have to deal with registry settings etc.

I noticed absolutely no lag when I was using the tools. Of all the tools I’ve been playing around with, applying strokes in Paint Tool is as smooth as cutting warm butter. And I especially like the results I get with Paint Tool’s watercolor brushes. Also, the magic wand selection reminds me a lot of the quick mask tool  in Photoshop; something I’ve always liked.

SAI Paint Tool. From upper left to lower right: sketch, ink over sketch, ink, paint, ink over paint, ink over paint on background

I’ve read somewhere on the interwebs that Paint Tool has some memory limitations as far as canvas size and brush count, but I can’t confirm this. One other possible red flag is that the tool hasn’t been updated since April of 2016. As much as I like the tool, lack of updates may turn me away, especially in a production environment.

Corel Painter Essentials 6

This program is a little bit more of a challenge to get comfortable with compared to the others. I really wanted to like this, and I was ready to drop my 240 bucks on Amazon for the full version instead of the Essentials, and that’s even the sale price ($400+ original price)! Unfortunately, as I continued to use Painter Essentials, the more I was disliking everything about it. It took me a while, and I’m glad I didn’t immediately drop my 50 bucks on it.

I think my problem with Painter is that it’s WAY too close to traditional media. Having to choose the paper surface is a little bit too much for me as a game developer. It might be good if I was creating a Paper Mario knockoff or Kirby’s Art Paper Adventure, but otherwise, I just felt really hindered by its UI. It’s like Corel took every aspect of traditional media and included all the inconveniences of it too. The UI is just short of having a turpentine bottle and a moldy washcloth object to use in between brush selections.

I managed to settle in with a select few tools, but the brush selection can sometimes be daunting to anybody who hasn’t used the equivalent traditional media in the past. However, I’ve tried Painter a few times before and have always liked the mobility of the color picker, so there’s that.

Painter Essentials 6. From upper left to lower right: sketch, ink over sketch, ink, paint, ink over paint, ink over paint on background

Every time I laid down a stroke, I felt there was a bit of lag, but of course, it depends on the brush too. I just felt like I was fighting the drawing tools, and it wasn’t providing the results that I wanted. Perhaps it was the default settings that turned me off. But, how then, can every other paint program provide decent defaults?

Painter is probably great for game concept artists, or traditional artists that are planning to transition to the digital medium. It just wouldn’t immediately fit into my gamedev workflow.

Krita

And now the tool I’m gonna gush over. I’ve tried Krita on an older laptop a few years ago. The results looked fantastic, but the performance was horrible. I wasn’t sure if it was more the laptop or the program. I didn’t want to spend time learning Krita back then, but now, the software has had time to mature, and it’s been established as a paint tool for artists, as noticeable from the amounts of community-created resource bundles, and its UI is very navigable and efficient. I especially like the rich context menu, which gives you quick access to common brushes and a color picker. I also like that the keyboard shortcuts can be set up for Photoshop or SAI Paint Tool users. It also has animation! I haven’t used it yet, and I doubt it’s as good as Toon Boom for that purpose, but it’s cool that it’s included. And on top of all that, it’s open source! What’s not to like about this program!?! Well, there are still performance issues, especially compared to the speedy UI in SAI Paint Tool. Fortunately my rig is powerful enough to not show these issues much. I also had to download a third party watercolor brush set, and it’s still not as impressive as SAI Paint Tool’s, but I think it’s still pretty good. I would like to start incorporating Krita into my normal game dev content creation workflow.

Krita. From upper left to lower right: sketch, ink over sketch, ink, paint, ink over paint, ink over paint on background

Autodesk Sketchbook

And finally, Autodesk Sketchbook. Nope. Not gonna do the subscription model. As much as I respect Autodesk and all that they’ve done for the digital creative arts, once they’ve switched to the subscription model, my consideration for any of their products has considerably dropped off. Sure, software nowadays is more of a service than one-and-done, release/repeat products, but as I see it, as a part-time indie developer, I will never be in front of any of these tools on a consistent basis, so why should I pay consistently? But… I’ll give it to Autodesk for releasing Sketchbook on mobile. I love it on my old Samsung tablet, even though I didn’t make full use of it. And even then, I sometimes switch over to Art Flow. Bottom line for Sketchbook Pro, I never even downloaded the trial due to the subscription model.

Other Tools That I Haven’t Mentioned Above

GIMP – I haven’t used GIMP lately, but if you need some paint program, I guess it’s functional. Last time I used it, in fact, every time I try it, I find it clunky, slow, disjointed, graphically buggy, but again, it gets the work done if you have no other options. Its feature set may be as rich or almost as rich as Photoshop, but good luck using it in a flow that makes you efficient and that doesn’t break your creative rhythm. But hey! It’s open source, so there’s that!

Paint.NET – This is my tool of choice for lightweight, quick edits that don’t require a lot of complexity. It will not necessarily allow you to produce fantastic art pieces, but it’s functional for doing graphical fixes and touch-ups without having as annoying an interface as GIMP. Its feature set is limited and is closer to MS Paint than Photoshop, but sometimes you need that simplicity. I sometimes refer to it as “MS Paint with Layers and Plugins”.

So there you have it. A comparison between four paint programs. I’m definitely leaning towards Krita because it’s powerful and free. How can you beat that? Photoshop Elements still has its place in the development workflow, though, as a general graphics editor; something that the more artsy focused paint programs may not necessarily be good at. But whatever paint tools you use for your game, remember…

Make it fun!

 

  • Adobe Photoshop Elements 2018
  • SAI Paint Tool 1.2.5
  • Corel Painter Essentials 6
  • Krita 3.3.3
  • Wacom Intuos3, 8×6
  • Windows 10
  • ASUS ROG GL753VE, Core i7, 4GB GTX 1050Ti
Posted in Art, Dev | Leave a comment

Too Long

Earlier this week, indie game developer Jake Birkett of Grey Alien Games published the Youtube video “You are spending too long making your game” (Alternate reddit source):

Since watching it, I’m taking a moment to step back and look at what I’ve done and where I’m heading. I estimate that it will take me another 2 years to finish the project that I’m currently working on.

My first reaction to this video was, “He’s right”. I’m a believer in “starting small”, and I would even preach it. But I can’t help feeling like a hypocrite if I can’t even follow that. Well, when I went full-time indie for a year, I did my best to make small projects with short dev cycles. I ended up releasing 3 mobile games: Power Tic Tac Toe, Number Crunchers, and Horde Rush. Each took progressively longer to implement, but also with increasingly better visuals and production quality. While Number Crunchers gets some downloads to this day, most likely due to the familiarity of its existing source IP, Horde Rush was pretty much dead on arrival. It had a few downloads at launch, but soon after, did not gain a following, and it eventually got buried by all the hundreds of other games released on a daily basis. Of course, I didn’t do any marketing for Horde Rush, and that’s definitely one of the many reasons it hasn’t taken off.

After starting to work full-time again, I changed gears and decided to work on a game that is a lot more ambitious than the three titles that I’ve released; something with the level of quality of say, a Gameboy/DS game. So far, it’s been moving along, and I’ve been having a lot of fun building it. I figured that if I’m going to work full-time again, I might as well work on something that I’m absolutely passionate about, and that may or may not take a long time to implement.

And then Jake’s video comes out. And he mentions that “spending too long developing a game” has exceptions. The first one being that if you currently have a day job, and you are working on your game on the side, the overly long dev cycle does not apply, as the income is flowing. Regardless, the thought of spending two more years on a game sounds daunting. And having more than one release in two years sounds more beneficial. You’d have the satisfaction and experience of finishing games, you’d have a lot more visibility with whatever audience you have, and/or potentially gain an audience, and generally, I would think it would result in a better quality of life, because you’re not slogging away on one game, not knowing exactly when you’ll be done. Let’s face it. Anything that’s 2 years out can’t accurately be determined to have a certain level of quality, features, or dev time. It’s simply an unknown.

I was eventually going to start a dev blog about my current game. That way, I can stay visible with the game dev community, possibly gain a small audience, and hold myself accountable. But I think I’m another 6-12 months out until I would feel comfortable exhibiting my work in progress. So, I thought of starting up another smaller project that would take a much shorter time to build, and would allow me to reuse some of my existing assets. I’ve planned on eventually working on this project, but after watching Jake’s video and reading all the comments about it, I’m highly considering moving this up on the schedule. As protective as I am over my current project, I don’t think I’d feel that secretive about the development of this new game based on Horde Rush. The IP (intellectual property) is already out there, and my initial gameplay ideas aren’t all that revolutionary. So, I would be more comfortable releasing dev updates, which can help out the gamedev community.

And while I’m trying to convince myself that this is the right way to go, I still have a lot of drive, passion, and some momentum going for my current game. Do I just kill that momentum? Will it be a refreshing change that will help me better see the vision of the game when I return back to it in a few months? Maybe I can try implementing both games in parallel. Not really. That never turns out well. I have limited time as it is with the full-time job. I couldn’t possibly ping-pong back and forth between both projects. Whatever path I choose, I don’t want to dwell on it for too long, because doing anything is better than doing nothing at all.

Posted in Industry, Thoughts | Leave a comment

Finding Time

Game developers are always on a different part of their journey towards completing their game at any moment in time. Maybe you’re just starting, maybe you’re finishing up, and maybe you’re stuck in the middle for the long haul. That “middle” is where I am in development, and sometimes there’s no end in sight. It’s especially apparent when life and the day job (if you’re not a full-time game dev) take priority. I’d like to share some of the “life hacks” that I use to get that precious time in to work on my game.

First, I have to set up the scene. I’ve been busy with work and life over the past 6 or so months, and I don’t see that stopping any time soon. That means I’ve had very minimal time to work on my game project. Let’s put it this way: I’ve used “5 hours per week” as my benchmark for getting work done on my game. If I can hit 5 hours, I’ll be pretty happy. That can come in different variations, like an hour a day after work at my Monday-Friday job, especially if I have plans during the weekend, or maybe a few minutes a day during the week with 2-4 hours on the weekend. It all depends on work and life. On rare occasions, I can manage 10 or more hours in a week if the opportunity is there. But I try my best to fit it in however I can.

But for the past 4-6 months or so, I’ve had far less time than 5 hours/week to do stuff. For several weeks, I’ve only had maybe an hour or two per week tops, which meant like 10-20 minute sessions.

Some weeks, I’ve just been way too tired to even work on the game. Sometimes I made it work. Forced it. Stayed up an extra 20 minutes, or even 5 or 10 minutes, after everything around me has shut down, just so I can put that little bit in to finishing my next small goal. And other times, I had to recognize that, instead of forcing myself to work on my game for 20 minutes, my body needs to just rest, because if I pushed it any further I most likely would get sick.

This has been my situation. And while I can anticipate this being the regular routine for the next several months, I remind myself that as long as I keep on moving forward, no matter how little, my creative spirit will stay alive, and give me hope that I will eventually finish this game. (Besides “hope”, having a development plan and source control are also necessary. You can find plenty of reading on those all over the web.)

Moving forward can also mean moving backward. Sometimes I have to fail to move forward. So if I only had 20 minutes to find out that the code that I wrote within the last 19 minutes is buggy, faulty, or just plain wrong, I accept that as forward movement, by noting in that final minute what did NOT work, so I can remind myself what NOT to do again. The more places I found myself repeating mistakes, the more time I spent into fixing those problems once and up front.

And when I’m away from my game, I do my best to “live in the moment”. I try to stay focused on that activity rather than wishing I was working on my game. It’s a distraction to think about the game all the time when I can’t do anything about it. That’s something I used to do a lot, and still have a tendency to do from time to time. And, I don’t mean “mobile planning” like jotting ideas, inspirations, and epiphanies into your smartphone. I mean those thoughts that have me constantly wishing I was in front of the computer instead. There’s no point in complaining, worrying, getting frustrated at something I can’t help. The added frustration just makes me ineffective at whatever I’m doing. It’s just not healthy.

I haven’t been the greatest at prioritizing things. Sometimes the laundry pile would get too high, the dishes would stack up, or the dog would go without a bath for too long. These are some things that end up falling by the wayside while there’s a game to be made! But one thing that I could de-prioritize is entertainment. I’ve given up plenty of games, movies and TV because I just didn’t think they were as important as my game. If I couldn’t get to my game in a day, let alone the chores around the house, why should I set aside time for movies or TV? Of course I make exceptions, and some entertainment sometimes can be good for the soul. Here’s my example. I’m a big fan of the DOOM franchise by Id Software. A new DOOM game was released in May 2016. I hadn’t had a chance to play it until May of this past year, 2017. I just put other things first, including my game. But once I hit a certain milestone and I was satisfied with where my game was, I set aside time to play DOOM. It still took me over a month to complete it, because I played the game in a piecemeal fashion due to life stuff, but eventually I finished it and I enjoyed every second of it, and it felt good for my soul.

I’m so excited for my game, and actually putting my work-in-progress out there for all to see, but I don’t feel that it’s at that stage yet. I want to make sure the work-in-progress that I post is more frequent, and meaningful, and I can’t exactly do that with short sessions to do things. So right now, I’m just building up.

And to all those game developers who are chugging away at their dreams and digging deeper, keep looking up, and as always…

Make it fun!

Posted in Uncategorized | 1 Comment

Multiplayer Network Solutions for Unity (Photon and PlayFab)

Aside from working on a side project to my side project, which I recently finished, I’ve gotten back to my original side project (my next game) and found myself researching on some tech for a large feature. Talk about “writing in code”! Spit it out! That tech I’ve been researching on is multiplayer networking solutions for Unity. There. Like the title didn’t give it away.

For the uninitiated, multiplayer games are games that can be played with other human beings across the Internet. Yes, this includes social games like those popular Facebook games of old*, and games like Pokemon GO, all the way to games like Call of Duty and World of Warcraft. Some of these games have competitive play and others have cooperative play, and sometimes there’s a combination of both. This, of course then, is different from single player games, like Crossy Road or Flappy Bird, which don’t involve multiple people playing together. Some games actually have both singleplayer and multiplayer modes, like the aforementioned Call of Duty. Nonetheless, I’ve already established that I’m writing about multiplayer here.

Game developers know full well that one of the most difficult systems to build is the multiplayer networking system of a game. I’m not even going to go into how difficult it is to build a Massively-Multiplayer Online (MMO) game, as that’s way out of scope of this article. If you’re still thinking about it, I’d highly recommend reconsidering your life goals.

But enough of the intro.

Unity Networking, Photon SDK, and PUN

For the past several days, I’ve been looking at potential network solutions for Unity, namely Unity Networking (Unity’s first-party solution) and Photon by Exit Games. From what I gathered, Unity Networking still needs some time to mature, whereas Photon is a more established networking package, with a long running track record. I decided to go with Photon for this reason, as well as for its healthy amount of documentation, so I’ll go into more detail about it here.

As of this writing, Photon has a sort of mixed personality. For Unity, it comes in two flavors. Photon SDK for Unity, and Photon Unity Networking. Whazzawha? Right. Photon SDK for Unity is available on the Exit Games website. Whereas Photon Unity Networking (PUN) is available as a downloadable asset package from the Unity asset store. The difference is that PUN is a wrapper around the underlying Photon SDK, to help you save time with the lower level groundwork code already implemented for you. PUN is also supposed to emulate the API of Unity Networking, so that it is more familiar to the Unity network application programmer.

So, I chose to use the Photon SDK for Unity. Why would that be if PUN already provides a lot of the underlying work for me? Well, there’s one feature that is currently not supported by PUN that I need for my next game: Persistence of asynchronous game sessions. I’ll go into more detail about what that is in a moment.

To make things more complicated, doing any Google searches for Photon Networking will inevitably yield results on “Realtime” vs “Turnbased” Photon. The hope for Exit Games was that Photon can be marketed for developing games that are fast-paced, and played simultaneously, or synchronously, between gamers (Realtime), and for games that are slower-paced, and played by one player at a time, or asynchronously, like Chess (Turn-Based). As of May 2016, Exit Games discontinued Photon Turnbased, which by itself sounds as if Photon would no longer support turn-based games. In reality, the Turnbased features have been merged into Photon Realtime. So that means, I’m using Photon RealTime for a turn-based game. How confusing! At the same time that Exit Games was attempting to simplify the delivery of their product(s) to its customers, it managed to confuse even newer customers like me.

Asynchronous Gameplay and Persistence

To support my next game, which is a turn-based game, I need to implement asynchronous gameplay and persistence via something called Webhooks/WebRPCs.

“Asynchronous gameplay” means that the players do not play simultaneously, together on the same turn. From a network programming perspective, this is far less difficult to implement than synchronous gameplay because with synchronous, realtime gameplay, there is no concept of “turns”. With synchronous games, developers have to implement the system such that every player connected to the game can give input and receive a result immediately, so as to produce the illusion that all players “exist” in the same virtual world. In reality, it takes fractions of a second, or even whole seconds to transmit that data across to all other connected players. Network programmers have to implement numerous tricks and techniques like dead reckoning and client prediction to generate the illusion that a player has moved, without any lag in time. Otherwise, if the game goes out of sync, the illusion is completely broken.

For each turn that a player takes in my turn-based game, the current state of the game has to be saved so that the next player can continue from that state. This is where persistence comes in.

So for persistence, or storage, of game sessions in progress, the Photon SDK provides Webhooks and WebRPCs to load and save game data; something that PUN does not provide.

Webhooks and WebRPCs go hand-in-hand for game clients to communicate with web servers. WebRPCs (Remote Procedure Calls) are used by clients to send messages across the network, so that web hooks on a web server can receive those messages and process them in a secure, authenticated environment. Note that web servers are your typical type of server for hosting web pages. So while in this case, a web server is being used as a game server, it could also be the host for web pages to convey that data, say, for players to check their progress, or the states of their game sessions. Also note that web servers are not used as game servers for real-time games. Servers for real-time games require support for higher loads and bandwidth, because they generally process a lot more network traffic than for turn-based games, to maintain synchronicity across all connected clients, as mentioned above. This is why web servers are more suitable for turn-based games.

And with all of that knowledge, I discovered that Photon does not provide web servers, only the hooks! Bah! Before learning about it, I thought Photon was going to be my one-stop shop for all my network and multiplayer needs for my game. At least, that’s what their marketing made me feel like what it was. In reality, a more seasoned network gameplay engineer probably would have been able to see past the bullet points and tell me that I still needed another component to get Photon working the way I wanted for my turn-based game.

Luckily, through Photon documentation (or somewhere on the Photon or Unity forums), I found out that PlayFab is the recommended solution that provides that web server that I’m looking for. Not only that, it provides some other good stuff that I’d need that Photon doesn’t provide, like user accounts, leaderboards, etc. Also, GameSparks is a competitor which provides pretty much the same thing, but I admit that I didn’t do much research into which would be better for me. Since PlayFab has a partnership with Photon, I decided to go with that.

PlayFab

Once I found out that I had to use yet another system besides Photon, my heart sunk. I was already feeling pretty overwhelmed with having to learn the new Photon API. I was reluctant to learn even more than I was planning to. But we’re game developers, right? We keep learning and work through it! That’s what we do!

Turns out PlayFab, after learning what they offer and how to navigate their browser-based Game Manager, provides quite a bit for the entry price of free. I like how it provides user accounts, tracks when and where they’ve logged on, and other analytics, such as segmentation, which is a business term that is beyond the scope of this post. They have this system called PlayStream which is intended for logging, but I haven’t figured this one out yet. What I was most interested in was, of course, how to implement web hooks for the Photon service.

PlayFab has a proprietary scripting system called CloudScript, found in the Automation section of the GameManager, which is essentially Javascript functions on the web server that handle the events sent via Photon from your game client. I find it a bit awkward and time consuming to upload and deploy cloudscript to PlayFab, but since it’s free, and they’re providing the web servers for me, I’m not complaining all that much. At least not yet… Well (that didn’t take long), trudging through more documentation on PlayFab, I discovered that the free tier of the service is severely limiting in terms of how much data you can save to their web server. It’s understandable, as it’s free, but it’s a fair warning to anyone who wants to try it out, that once you roll a game into production and release, you’ll most likely need to choose a non-free tier to get all your data persisted on their servers. 

Keep On Keepin’ On

At the time I am writing this, I’m still in the midst of working through Photon and PlayFab so that I can get a working game flow for the player. While there’s a wealth of information on both services, it’s very fragmented and difficult to piece everything together. In future posts, I’d like to go more in-depth with my Photon and PlayFab setup, because I’m finding it a pain to get through right now. Perhaps others planning to take this route will benefit from my findings. In the mean time…

Make it fun!

 

 

* Of course Facebook is not that old. But in “technology-and-video-game” years, 4-5 years is like 4-5 decades…. Is Farmville even still a thing?

Posted in Dev, Programming | Leave a comment

Time-lapse Gamedev Session Recording

Here are a few tips for some of you indie game developers out there, that are looking to show off some of your work via time-lapse video.

CamStudio

Download CamStudio, which is a free and open source video capture program.

Use the following settings:
Options > Video Options... > Compressor: Cinepak (default)

Uncheck Auto Adjust at the bottom. This will allow you to adjust the Key Frame frequency, and the Framerates.  I set Set Key Frames Every 1 frame(s)

And for framerates,
Capture Frames Every 1000 milliseconds
Playback Rate at 2 frames/second


This means, that while recording, CamStudio will capture the screen every 1 second, and it will play back twice as fast.
After watching a recording at this playback speed, it was still a little too slow, but most video players nowadays have a speed control, so I wasn’t too worried about it, especially if I decide to export these time-lapse videos to animated GIFs (more on this later), I would have the opportunity to set the speed prior to export.

Another setting that I like to enable is even pixels (which for whatever reason I don’t see in v2.7.3). This is just to allow more video players to run the resulting video, as an odd number of pixels tends to result in encodings that aren’t really friendly to some video players.

Be sure to set your recording region and output directory accordingly, and you’re ready to rock.

When you hit Record (the obvious big red button), corner brackets will pulse at the edges of the recording region, at the specified Capture Frames Every setting, so for example, if I was using 1000 milliseconds, I would see the brackets pulse every second. What’s great about this is, for time-lapse recording, CamStudio doesn’t eat up a lot of resources to capture video while you are doing what you are doing.

Animated GIFs

To create an animated GIF, you need a sequence of still images, or frames, that you would then re-assemble into an animated GIF file.

Converting Video to Frames

If you wanted to convert the time-lapse video you just created above into an animated GIF, you’ll have to extract still frames from the video as a sequence of images before assembling the GIF.

I like to use avidemux (another free and/or open source software program). You can save a video, or portion of a video loaded into avidemux, export it as frames. Be sure to install avidemux 2.5.x, as 2.6.x does not have this feature.

Capturing Frames Directly

Alternatively, you can use a program to capture time-lapse still frames, bypassing the video recording stage altogether. Apparently there are a number of applications that create time-lapse video and/or screenshots, but the one I tried was chronolapse after stumbling across this article.

chronolapse has the option of capturing screenshots or images from a webcam, or both. The program outputs a sequence of jpg images that you can later assemble in another program for creating animated GIFs. One program you can use to do this is GIMP. There are far easier-to-use commercial programs to do this entire process, but I wanted to keep the software in this article free and/or open source.

Exporting Frames to Animated GIF with GIMP

Once you have the sequence of still images, you can use GIMP to export the final animated GIF.

To do this, open up GIMP and create a new image with the same dimensions as the exported images.

Then, select all the images in the sequence in an explorer window, and drag them onto the Layers window to load each image as a layer; be sure to drag the first image in the sequence first, or else the sequence may get out of order. This process can take a long time if you have a large number of images and/or the dimensions of your images are large.

Once all the images are loaded into the Layers window, don’t forget to delete the first frame that contains only a blank image from when you originally created the file. Before exporting, you may have to reverse the order of the images in the layers by using Layer > Stack > Reverse Layer Order, because GIMP is weird sometimes. You can then click on File > Export... This will prompt you to choose your directory and the file type (GIF), and then you can click on Export, and it will bring up this dialog:

Select As Animation, and your looping and delay options. Once you click on Export here, it may or may not again take a long time to process, depending on the number of frames and dimensions of your image.

One last thing I should mention is, animated GIFs can be fairly large for the web, depending on the length and dimensions of the animation. webm is another animated image format that is pretty popular online now, is relatively smaller in size to animated GIFs, and you can find some converters with a quick search.

And done!

Here’s an example of what I used these time-lapse techniques for (it’s a fairly large GIF; apologies in advance):

I was 3D modeling the characters Dipper and Mabel Pines from the show Gravity Falls for an eventual 3D printed gift for my significant other. It turns out that a lot of the principles for 3D modeling for game development also apply to 3D printing. Maybe I’ll write up some future articles on the subject…

Here’s a summary of the tools I just mentioned:

Anyway, happy developing!

Make it fun!

Posted in Dev | Leave a comment

Forecast: Stormy

My colleague hired me to do a contract art piece for him. It’s a logo to celebrate the release of the 100th episode of his YouTube video channel.

This is what it looks like:006

Yes, his name is Storm. Yep, Storm. I’m sure he gets that a lot. You know, your reaction; that face that you’re making. His channel is all about games. He does reviews, and they’re pretty damn funny and entertaining and informative.

Anyway, I encourage you to take a break from whatever it is you’re doing, be it developing a game or reading about Under the Weather.

Here’s the ep:

Anyway, that’s enough for the plug.

Make it fun!

Posted in Thoughts | Leave a comment

What’s Happening in the Industry?

So, let’s talk about games. As I write this, Pokémon GO is still going strong, No Man’s Sky has lost 90% of its user base in two weeks, and the Rio Olympics have wrapped up.

I’ll tackle the Pokémon GO craze first.

pokemon_go_logo

I’m playing it. Who isn’t, right? I didn’t plan on playing it, but I got slowly sucked into it. And so now, my better half and I go out hunting some nights. But seriously, what is it about this game? On the surface, it’s just some mobile, social game with AR (Augmented Reality) and GPS (Global Positioning System) features. But those are just some of  the technical components of the game that form the whole. The magic sprinkle on top is the IP (intellectual property) tie-in, with the Pokémon monsters, right? Well, yes and no.

Pokémon GO’s success did not happen overnight. In this post on Reddit, Niantic CEO John Hanke describes that the game was about two decades in the making. I believe that Pokémon GO’s success goes much deeper than the integrated IP, and the use of cameras and GPS, and even beyond the established database of information used for the game. As a piece of software in general, it’s a finely crafted, well designed game. It contains many standard staples of RPG (role-playing game) mechanics, such as XP (experience points), and several other forms of currency, like “stardust”, “candy”, “coins”, as well as many statistics, like combat power, and size and weight, for each monster that you catch. You can evolve Pokémon into more powerful forms, and you can hatch them from eggs, which adds an element of randomization, anticipation, and surprise to the game.

All of these game design elements combine to make an overall cohesive experience, from the moment-to-moment gameplay of throwing curveballs to gain extra points, all the way to the metagame of territorial competition at the various gyms across the map. I realize that some of these concepts are not foreign to existing Pokémon fans who have played previous games based on the IP, or have watched the animated series. This is all new to me, as I was never into Pokémon , and I barely knew any of them beyond the classic Pikachu, Charmander, Bulbasaur, and Squirtle.

gold_rush

Naturally, the game development community immediately jumped on any clues, ideas, and research on how to make a Pokémon GO clone, so that those opportunistic types can cash in on the trend, while the more clever developers would pump out tutorials and resources to easily plug into your own game to get you along your way; providing the shovels and blue jeans, so to speak. But if Pokémon GO took well over a decade to slowly build its data infrastructure, what makes people think that they can emulate Niantic’s success? As I mentioned earlier, the individual technological features of the game is not what makes the game stand out. For example, the AR component is still considered a gimmick, as the more seasoned Pokémon GO players turn this feature off, because the non-AR view gives them more control while trying to capture those elusive creatures.

So from a developer’s perspective, a game like Pokémon GO can never become an overnight success. There is just too much technological infrastructure and experience employed to make the game as polished as it is, server woes notwithstanding. Another example of this phenomenon is the story behind Rovio, the company that developed the game, Angry Birds. Rovio overcame many failures, before reaching their success on their smash hit.

And now, you’re lucky to find a piece of merchandise that doesn’t have an Angry Birds character on it! Anyway, I can probably keep going on about Pokémon GO, as there’s plenty to analyze about the game, from different angles of game development. So I’ll quit it here for now.

On the flip side, there’s a game called No Man’s Sky.

no_mans_sky_logo

To summarize, No Man’s Sky is a game that was recently released after several years of having generated hype, so there was plenty of anticipation for this game. Many players are upset about what the product was on the first day of release, and what it is today. It turns out, the game did not live up to its high expectations, as it was released with many missing features that the developers “promised”. After two weeks on the market, the game’s user base has dropped off dramatically.

You see, one of the many challenges, if not the biggest challenge, for independent game developers, is marketing their games. They’d rather be building, creating their game than spending time telling people about it. And then, when it comes time to launch, the game ends up flopping, or at the very least, not reaching the audience that it is intended for. And that’s why marketing is such a huge piece of the puzzle. The video game industry, especially the independent game industry, is no longer in a state of an “if they build it, they will come” mentality. Perhaps that was the case during the Braid and Limbo “era”, but now,  the tools are readily accessible at little to no cost. All an aspiring game developer needs to get started is to “level up his/her skills, put in a lot of elbow grease, and give it plenty of time to bake.” But in order to increase the chance of success, you have to throw in as much time, effort, and basically, blood, sweat and tears into making a product that you think people will like (more on this another time), and then half the battle is done. Just half?!? Yes, just half. Marketing is that other half, and that means communicating to the outside world; screaming at the top of your lungs, that you have a product that you’d like to share. Simply put, the more people who know about your game, the more the percentage of people that will actually try your game.

Anyway, off of the tangent… No Man’s Sky was marketed EXTREMELY well. The hype train was coming along strongly, which is a good thing… but only for a good, complete game. Without any substance to back up the marketing, No Man’s Sky fizzled out. It lacked any staying power. Typically, games can last several weeks to months, and some rare successful games have mass followings that will make it last for years after release, as in the case of games like World of Warcraft and EVE Online. Instead, No Man’s Sky saw a lot of players request refunds from the various distributors of the game.

Among all the rare successes in the game industry, No Man’s Sky represents yet another failure of game development, and software development in general. Godus is a game by renowned game designer Peter Molyneux, created by his independent studio 22 Cans. The game’s notoriety grew as the direction of development ran askew, and like No Man’s Sky, promised rewards didn’t get delivered. The game was initially funded by a KickStarter campaign, and the company over-promised and under-delivered. The story, written by Nathan Grayson over at Kotaku, is intriguing if you have the time to read it. Some other notable failures are the Batman game Arkham Knight released on PC and Colonial Marines, a game based on the popular Alien/Aliens movie franchise. Both games had high hopes, only to be riddled with bugs and performance issues, and in addition to that, lack of content, in the case of Colonial Marines.

So well, this is a quick look at the most popular trends in the video game industry in 2016, at least, as of the end of Summer. Typically, the industry has a lot more cooking around the Winter holidays, for the obvious reason that kids are looking to get electronic gifts from their parents Santa that are not Tiger handhelds.

As far as the Olympics goes, well, I hadn’t paid much attention to it, other than to all the devastating stories about Zika, green pool water, pollution, and a disgraceful “bro” story. You can go look those up for yourself, because some of them are too disgusting to even write about. I’m glad it’s all over though, so we can get back to regularly scheduled programming.

Well, that’s about all I feel that I want to write about right now. I’ve been behind the scenes, hard at work on my next game, but I’m still not ready to reveal anything yet.

Until next time,

Make it fun!

 

Posted in Industry, Thoughts | Tagged , | Leave a comment

Plotting a New Course

Under the Weather is taking a change in direction for the foreseeable future. I started working at a great company that is completely unrelated to games, which means I’ll be scaling back the time I spend on Under the Weather games, websites, and social media. Essentially, the projects I work on for Under the Weather are now relegated back to “hobby” status.

The Reasons

Anyone’s first thought into why I would make this decision can be that I am running out of money to continue funding a startup. While I am not immediately seeing the return on investment within the first 12 months of effort, money was not one of the more important reasons for the change. Don’t get me wrong. I’m not rich, but I wasn’t going to start panhandling either.

If anything, it was a personal decision. Life happens, and some events in life take higher priority than others. I don’t really want to go into more detail than that.

The Strategies

Making a conscious decision to look for a job required a significant mindset change. I was already in the midst of developing my next game (and I still am, but at a lesser capacity now), and then I had to update the resume, brush up on those academic interview questions, and generally get ready to get back to working for a company that’s not my own. I found a few prospective places that I could work for, but luckily I found a software engineer position at a robotics company whose products are for the scientific community. So yeah. For science!

The place I’m working for allows me the amount of creative freedom on my off time that working at a game studio does not. One of the drawbacks I had while working at a game company is that I felt creatively starved.  For one thing, working on your own game on your personal time is considered a conflict of interest. For another, working at a game studio tends to use so much of your creative energy, that you don’t really have any left after going home for the day. I have to say though, that working in the game industry is a great experience, but during crunch time, when you absolutely need to ship the game, it can get incredibly stressful and draining.

The Future

So, with my free time a lot more limited now, I have several avenues I wanted to explore for developing and growing Under the Weather. I’m not ready to reveal anything yet, but at some point, I’d love to divulge more details about the first year of development of the company and products. There are plenty of game development stories out there, and for some reason, I personally can’t get enough of them, so this time, it’s my turn to contribute. This probably also means that, perhaps now, this blog will be a little bit more free form, in the sense that, before I started this whole Under the Weather thing, I had no idea how to blog, and how I should blog for a company. Well, this is me. I’ll write about stuff. Games, software, and things related. So for my next post, I’ll probably get to talking about Pokémon GO…

 

Make it fun.

Posted in Announcements | 2 Comments

How to Extract Layers from a Photoshop File with ImageMagick and Python

For a project that I’m working on, I need a way to extract each layer of a Photoshop PSD file and have them written out as separate PNG image files. To do this, my first thought was to use ImageMagick. ImageMagick is a graphics library used to manipulate images and convert them to different graphic file types, among many other things. I’ve used ImageMagick before, but I don’t use it enough to remember all of the syntax by heart, so I had to do a lot of google searches to compile this solution together. I could have rolled my own solution, but time is the enemy, so using any sort of libraries that saves you hours, days, or weeks, is an obvious win.

Requirements

The requirements for this system are pretty simple. A Python script can be run from the command line, given the path to a Photoshop PSD file. After the script is complete, the folder containing the PSD file now also contains all PNG files for each layer in the PSD file.

Overview of Extracting Layers from Photoshop with ImageMagick and Python

Overview of Extracting Layers from Photoshop with ImageMagick and Python

Pretty simple, right? Not quite.

As I was implementing this solution, I discovered some information and processing techniques that aren’t immediately available through ImageMagick’s commands.

The most basic command to extract layers from a PSD file is straightforward enough:

convert <filename>.psd[1] <extracted-filename>.png

Where, the number 1 is the index of a layer in the PSD file. But here are the problems I ran into:

Irregular Image Sizes for Alpha Layers

If the layer is an alpha layer, all of the transparent pixels on the edge of the image on that layer are not accounted for in the dimension of the output file, thereby resulting in images with varying dimensions. For example:

Irregular Alpha Images when Extracting Layers from Photoshop with ImageMagick

Irregular Alpha Images when Extracting Layers from Photoshop with ImageMagick

This is a no-go for my purposes, because I need to later re-composite the layers, and if each output layer is a different size, they can’t be easily merged back together.

Unable to Export by Layer Name

This is another feature that I was expecting to use in ImageMagick that isn’t actually there.

To export a layer, you have to use the index rather than the name of the layer. I suppose this change isn’t absolutely necessary as a requirement for everyone, but I feel that it’s a lot more convenient to specify the name of a layer that’s easily cross-referenced by human eyes in the Photoshop file, as opposed to having to count what index is required in the layer stack. Not only that, you can do other selection tricks, like filter layers by specific names, which is actually the real purpose for supporting this.

So those are the two major problems I ran into, and that’s the reason why I chose Python for this solution.The solution below could very well have been done using batch scripts, or some other scripting language, but I’m a Python user. There are multiple steps to get this working. In the Implementation section, I’ll spill out all the details.

Setup

Before I dive into the details, I want to mention that this article already assumes that you have your environment set up to run these operations. If you’re sure that it’s set up, feel free to skip ahead to the Implementation section.

Photoshop – I use Photoshop Elements, but you’ll obviously need some program to author PSD files for processing.

ImageMagick – I initially started implementing this with version 6.9.3, but have since upgraded to 7.0.1. I was taken aback a bit, since by default, versions 7.0.+ have marked the convert command as legacy, and the solution in this blog post uses the convert command. If you are using this version, be sure to check the option to “Install legacy utilities (e.g. convert)” before installing it. Older versions do not have this problem.

Python – I’m using the 2 series, not the 3 series for this solution. Be sure that you can run Python files directly from anywhere in the file system, without having to specify python.exe in front of it. For me, I had to do 'regedit', and modify the value in HKEY_CLASSES_ROOT/py_auto_file/shell/open/command to:

"C:\Python27\python.exe" "%1" %*

Moving along…

Implementation

Fixing the Alpha Image Size Problem

Let’s solve the problem with the irregular alpha image sizes first. I stumbled across the answer on this thread here. But I’ll explain it a little further here, as the syntax is a little strange.

convert <filename>.psd[0] <filename>.psd[2] ( -clone 0 -alpha transparent ) -swap 0 +delete -coalesce -compose src-over -composite <extracted-filename>.png

The first two parameters are the first two image files in the “sequence” for ImageMagick to process. The index (i.e. [0] and [2]) indicates the layer to process. Layer 0 is not really one of the layers in the PSD, but it’s actually the flattened image of all layers in the PSD. Layer 2 is the second layer in the PSD, for this example.

The part of the command in parentheses are options processed as a unit, before moving on to the rest of the options. It creates a clone of the first image in the sequence, and then wipes it clear as an alpha image that’s completely transparent. This new image is tacked on as the third image in the sequence.

The next option (-swap) swaps the last image with the first image in the sequence, and the +delete option deletes the last image (which used to be the first image) because we no longer need it.

I’m not actually sure why -coalesce is needed here, but -compose src-over sets up the image for alpha compositing such that the overlaying image is blended according to the transparency in that layer. The -composite option then performs the compositing of the two images, and outputs the file as <extracted-filename>.png.

Whew! That took a lot to explain, but I hope it at least gives an idea of how ImageMagick is processing the layers in the PSD to produce the resulting images.

I realize that there may be other solutions to this problem, but this is the one I found that actually worked for me. If you have a solution that is more elegant, feel free to ping me, and I can add it here.

Exporting Layers by Name

We handle exporting PSD layers by name in two parts. The first part is getting the layer names, and the second part is using those names. All of the code for this part uses Python.

Part I – Getting the Layer Names

Here is the file in its entirety. We’ll discuss the major points about the code after you take a gander.

Download

#  PSDLayerInfo

# Copyright (c) 2016 Under the Weather, LLC
#
# 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.

import os
import sys
import subprocess
import string


class PSDLayerInfo:

    def __init__(self):
        self.layer_names = []

    def process(self, argv):

        if len(argv) < 2:
            print('No file specified')
            return;
        
        inputFile = argv[1]
        # imagemagick command to print out information about the input file
        identify_cmd = 'identify -verbose ' + inputFile

        # check_output runs the specified command, and writes the result string to the var
        psdInfo = subprocess.check_output(identify_cmd, shell=True)

        # copy the info to be consumed
        data = psdInfo
        while data:
            data = self.find_layer_name(data)

        for name in self.layer_names:
            print(name)

    # partitions the string based on the "label: " string
    # collects the names in layer_names
    def find_layer_name(self, inputStr):
        parts = inputStr.partition("label: ")
        lastPart = parts[2]
        if lastPart:
            index = lastPart.find('\n')
            if (index is not -1):
                self.layer_names.append(lastPart[:index])

        return lastPart
    
def main():
    argv = sys.argv
    layerInfo = PSDLayerInfo()
    layerInfo.process(argv)
    

if __name__ == "__main__":
    main()

So, this script accepts the name of a PSD file as a parameter.

The first notable item is this line:

identify_cmd = 'identify -verbose ' + inputFile

identify is an ImageMagick command, and we are using it here to get some information about the PSD file; specifically, the layer names.

psdInfo = subprocess.check_output(identify_cmd, shell=True)

subprocess.check_output() is a Python function that runs an external program and pipes the output from that function into a byte array, psdInfo.

psdInfo contains tons of information about the PSD file. The function find_layer_name() takes that string, iteratively parses it, and collects all the layer names identified by every occurrence of the "label: " string in psdInfo.

def find_layer_name(self, inputStr):
   parts = inputStr.partition("label: ")
   lastPart = parts[2]
   if lastPart:
      index = lastPart.find('\n')
      if (index is not -1):
         self.layer_names.append(lastPart[:index])

   return lastPart

The partition() function separates the input string and outputs a 3-tuple as 3 string objects, the delimiter "label: " being the second string object. Since we're only interested in the stuff after the "label: " delimiter, we always look at parts[2], being the last part of the string.

Once we have the layer names, we simply print them to the output.

Part II - Using the Layer Names

So, now that we have a way to collect all the layer names from the PSD file, we take those layer names, and export each layer individually, using the convert command that we used to solve the irregular alpha image size problem above.

Download

#  PSDLayerExporter

# Copyright (c) 2016 Under the Weather, LLC
#
# 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.

import os
import sys
import subprocess
import string

class PSDLayerExporter:
    def process(self, argv):
        print("Layer exporter")

        if len(argv) < 2:
            print('No file specified.')
            return

        self.inputFile = argv[1]

        out = subprocess.check_output('PSDLayerInfo.py ' + self.inputFile, shell=True)

        layers = out.split('\n')

        index = 0

        for layer in layers:
            index += 1   
            if layer and (layer.find("base") is not -1 or layer.find("detail") is not -1):
                print("layer: " + layer)
                self.export_layer(index, layer)

    def export_layer(self, psdIndex, layer_name):

        extractedFilename = ""
        extIndex = self.inputFile.rfind(".psd")
        if extIndex is not -1:
            extractedFilename = self.inputFile[:extIndex]

        extractedFilename += "_" + layer_name + ".png"
        cmd = self.inputFile + "[0] " + self.inputFile + "[" + str(psdIndex) + "] ( -clone 0 -alpha transparent ) -swap 0 +delete -coalesce -compose src-over -composite " + extractedFilename;

        commandStr = 'convert ' + cmd

        subprocess.call(commandStr, shell=True)
        
def main():
    argv = sys.argv
    layer_exporter = PSDLayerExporter()
    layer_exporter.process(argv)
    

if __name__ == "__main__":
    main()

For the most part, this file uses common Python syntax and methodology, so I'll again, just point out the major points of interest.

out = subprocess.check_output('PSDLayerInfo.py ' + self.inputFile, shell=True)

Oh look, it's our old friend subprocess.check_output()! We used this function in the other script, to get the output from the ImageMagick identify command. This time, however, we're using it on the PSDLayerInfo.py script that we just discussed above! And this time, we know that the output will be a endline-separated string of all the layer names in the PSD file. Handy!

def export_layer(self, psdIndex, layer_name):

    extractedFilename = ""
    extIndex = self.inputFile.rfind(".psd")
    if extIndex is not -1:
        extractedFilename = self.inputFile[:extIndex]

    extractedFilename += "_" + layer_name + ".png"
    cmd = self.inputFile + "[0] " + self.inputFile + "[" + str(psdIndex) + "] ( -clone 0 -alpha transparent ) -swap 0 +delete -coalesce -compose src-over -composite " + extractedFilename;

    commandStr = 'convert ' + cmd

    subprocess.call(commandStr, shell=True)

export_layer() does most of the work in this file. The first block simply takes the PSD's filename, and modifies it to append the layer name and PNG extension, resulting in the extractedFilename. With that, we call the convert function as mentioned above. Since we don't need any output from this operation, we just call subprocess.call().

 for layer in layers:
     index += 1 
     if layer and (layer.find("base") is not -1 or layer.find("detail") is not -1):
         print("layer: " + layer)
         self.export_layer(index, layer)

Last thing to note here, is that we are looping over all layer names, but only exporting the layers with either "base" or "detail" in their name. This is what I mentioned earlier, about being able to filter out exported layers based on the names of the layers in the PSD. It's not necessary, especially if you know absolutely how many layers and in what order you want your PSD asset files to be in, but it definitely makes it more convenient.

Conclusion

So that wraps it up! Automated PSD layer extraction from now until.... forever! Or more realistically, until Python, ImageMagick, and/or the PSD file format are deprecated, which is probably not any time soon, or even within the next decade or so. But if that is ever the case, well, hopefully I'll have another solution by then. Heck, there might already be another solution that's more elegant and runs faster now, but I do not yet know about it. For now, this works for me. Until next time...

Make it fun!

 

 

  • Adobe Photoshop Elements 9 (for authoring PSDs)
  • Python 2.7.10
  • ImageMagick 7.0.1 (with "convert" command installed)
Posted in Dev, Programming | Leave a comment

Number Crunchers Now Available on iOS

That’s right! Number Crunchers, which was only available for Android for the past several months is now available for the iPhone and iPad!

Play a classic numbers game with a new look and feel! Get it here on the App Store today.

iOS Download

muncher_apple

 

Posted in Announcements | Leave a comment