Great! I'll replace the rom on itch with this one.
Sorry about the hassle of the bug!
Hmm, in that case I've probably uploaded the wrong version of the ROM. I had a version that was adapted for saving for specific flash chips, but would crash in other cases that didn't support that chip. I'll see if I can dig up the version that saves to SRAM (which is what emulators usually emulate)
I finally got all the scripts recorded, and decided the game was "done" and ready for some friends to test.
Thanks to those friends, I found a few things to improve:
Well, the "testing" part of things always produces more work.
I have a bunch of audio clips, about 15 of them, which are all about 30 seconds long. I've been using LibGDX's Music class for them: I pre-loaded them in the AssetManager, then retrieved and played them when needed. It worked great on desktop. It worked great on small tests on my phone.
But on a full playthrough on my phone, the later musics just wouldn't play. At all. Silence. Even worse, LibGDX seemed to think they were playing, so I couldn't detect that they had failed to play.
I was about to beat my head into the wall, when I noticed this line from the documentation about Music:
Music
instances are heavy, you should usually not have more than one or two at most loaded.
Oops. I switched things around to only load the Music as soon as it was needed, and to dispose the old Music as soon as it stopped. That did the trick, and now all the sounds play correctly. I guess it pays to read the documentation!
Well, the game is nearly done. I spent a little while tweaking things, adding vibration on my fake phone call ringing screen, and so forth. This just might be the simplest and non-game-est game in the jam, but I'm just happy to finish something, and to have it be something I'm at least somewhat proud of, because I think it's vaguely interesting.
Last night's progress was tangential to the game itself, but because this is a sort of story/alternate-reality sort of thing, I decided I needed a real web page to go along with the fictional foundation in the game, (with a link in the app back to the web page). Turns out you can get a .space domain for 1 year from NameCheap for only $2 or so, which is pretty awesome.
I did spent a little while today trying to make the html version work, so people without Android devices can see the game run just by visiting the web version. But turns out that I'm using FreeType, which isn't supported on the web/gwt target. I don't really have the energy to factor that out into platform-specific code, so I'll just end up losing anyone that can't run the android or java version :-/
Oh well.
At this point, the only things left are getting my wife to record her voice part, and test, test, testing.
New years eve, sitting at home working on my game. Yes, I have young children.
One of the fun things about writing code for a jam is the "get it done" mentality, which means writing something simple and as straightforward as possible, instead of a more engineered solution.
In this case, I have a small conversation tree, with 5 or 6 recorded vocal tracks that branch depending on the player's choices. In most cases, I'd write some sort of system for managing the decision tree, and making it data-driven somehow.
NOT THIS TIME! This decision tree is small, so it's all coded with a big block of IF statements. Get it done, I say! The good part of this is that I'm actually almost finished with the bulk of the code at this point!
Well, I'm waiting on another voice actor (my wife, who has a sore throat, hopefully she'll get better soon!) so I decided to spend a little time working on my new skin.
First thing to do grab some graphics, which I found at
openGameArt. Then, the hassle of turning it into a skin. I started trying to use cobolfoo's gdx skin editor, but it has some bugs that make it hang and die on linux. Ugh. So I started debugging. It's always exciting when you spend your time fixing tools instead of working on the game itself. Although this turned out to be a really easy fix. Next step was to make a pull request to submit my fixes back, when I realized that somebody else had already forked it and made this fix and a few others. No idea why his code didn't make it back into the original, but I decided to go ahead and use it instead.
Now, turns out that with a better-looking skin, this thing is a bit cooler:
Ah, finally back from Christmas with family (would you believe there is ZERO internet where my parents live, you can't even get a cell phone signal!)?
Finally back at the game jamming. I've been purposely vague about some aspects of the game, because being more of a story-oriented game, I don't want to reveal too much of the story so far. I will say that I'm finding myself putting more and more code in my platform-specific adapters. The next thing I wanted to do, after the player answers the fake call, is pipe the audio through the actual phone earpiece instead of the main speaker outputs. I was hoping this would be fairly simple, but it ended up taking a bit longer than I expected.
It's a fairly straightforward call that you make on the Android MediaPlayer instance, but unfortunately (for my purposes here), libGDX keeps everything really encapsulated, and doesn't expose the MediaPlayer in any way. Which means instead of being able to use libGDX's Music class, I had to have a big chunk of platform-specific code for playing the call audio. For desktop, I could still use the Music class, but for Android, I had to drop down to using the Android MediaPlayer class myself.
Actually routing the audio was pretty easy, which I'll note here for the future:
public void startPhoneCallAudio() {
mediaPlayer = new MediaPlayer();
try {
AndroidFileHandle aHandle = (AndroidFileHandle) Gdx.files.internal("audio/governmentCall.mp3");
AssetFileDescriptor descriptor = aHandle.getAssetFileDescriptor();
mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
Gdx.app.error("error", "error", e);
}
}
The other interesting platform-specific thing that I ran into was trying to spoof the nice "end of call" tone that you hear when your call ends. After some googling, it turns out that it's not an audio file, but an actual DTMF tone, which you can generate with Android's tone generator:
public void playHangupSound() {
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, 80); //80 is volume
toneGenerator.startTone(ToneGenerator.TONE_PROP_PROMPT, 200); //200 is length
}
Other than these tweaks, I've mostly been doing UI work, trying to get things cleaned up a bit. We're getting there!
Well, I haven't had much time the last couple days, between work, Star Wars, and some family time. Finally today I got back into coding. One of the parts of this game is faking out the player, trying to make it seem like they're getting a particular phone call. I took some screenshots of the phone call UI on my phone, but one of the most important pieces is getting it to play the player's actual ringtone (as an aside: my game isn't going to work very well on the desktop!).
I had to use an adapter (similar to the suggestions on this page) to get platform-specific code for android, and tried about 15 different suggestions from Stack Overflow to get a repeating ringtone. None of them ended working, but this did:
public void playRingtone() { Uri defaultRingtoneUri = RingtoneManager.getActualDefaultRingtoneUri( activity.getApplicationContext(), RingtoneManager.TYPE_RINGTONE); defaultRingtone = RingtoneManager.getRingtone(activity, defaultRingtoneUri); defaultRingtone.play(); } public void keepPlayingRingtone() { if (defaultRingtone != null && !defaultRingtone.isPlaying()) { defaultRingtone.play(); } }
(Wow, this editor sucks)
Anyway, with the fake graphic for an incoming call, and the actual ringtone, it definitely feels like a real incoming call. We're getting somewhere!
Today's short afternoon spurt of work was less about programming, and more about preparing and collecting assets I needed.
I recruited a friend to be a voice actor, and prepared his script. Hopefully we'll get his part recorded soon. Then I spent the rest of the afternoon downloading and editing a bunch of creative commons audio samples of background static, making sure I have enough variety in how they sound. Then loading them into Audacity, and taking screenshots of the waveforms.
Now I need to go into the GIMP and clean up those screenshots, to be able to display and scroll the waveforms across the screen when the player clicks on an area.
The fun thing about a jam like this is that I spend more time "getting something working" instead of polishing everything. In this case, when it reaches the end of my waveform graphic, it jumps a bit when starting over. For a more polished game, I'd spend some time trying to make that transition work right. Not here (at least, not yet!). Move on, and get more done!
Wow, the scene2d framework has come a long way since I first looked at it, in some pre-1.0 version of LibGDX. In the last hour since the kids have been in bed, I've got almost half of my game UI mocked out using it, and switching from the draft/mockup to the "real thing" should be as easy as modifying the skin file, and then slightly nudging/resizing things.
I'd show some code here, but it's all so plain simple, I'm not sure what to even say. It's all super simple layout stuff, along the lines of:
private Window buildControlWindow() { float paddingLeft = 120; Window window = new Window("Signal", getSkin()); window.setPosition(0, 0); window.setSize(LifeInSpaceGame.WIDTH, LifeInSpaceGame.HEIGHT / 3); window.setMovable(false); window.setResizable(false); Label label = new Label("Radio Filters", getSkin()); window.add(label).padLeft(paddingLeft).colspan(3).expandX(); window.row(); Button filter1 = new TextButton(" Filter 1 ", getSkin(), "toggle"); window.add(filter1).padLeft(paddingLeft).expandX().padTop(10); window.row(); Button filter2 = new TextButton(" Filter 2 ", getSkin(), "toggle"); window.add(filter2).padLeft(paddingLeft).expandX().padTop(10); window.row(); Button filter3 = new TextButton(" Filter 3 ", getSkin(), "toggle"); window.add(filter3).padLeft(paddingLeft).expandX().padTop(10); window.row(); return window; }
This builds the panel in the bottom right that lets you apply different "radio filters" to the radio signal audio that's coming in from the selected star, to help you try to pick out whether there are any signs of intelligent life coming from that star.
The next task is going to be the first somewhat challenging one: to have a cool waveform image scrolling by on the bottom left side of the screen to match the radio sounds that you hear when you tap on a star. I have some ideas about how to make it work really easily, but it might take a little finagling.
And here we have some much needed instructions. I'll flesh out the text later.
Well, the baby was napping, so I had about an hour to work on this again this afternoon. Because this game has very little fast animation or action, and is UI-heavy, I decided to do it all with LibGDX's scene2d/stage framework.
The nice thing is that with the skin framework, I can use the sample skin to get things up and running for a quick prototype, then later, if I actually have time, I can go back and refine the graphics!
Currently I've got a single screen, where the vast majority of my code lives. I load a few textures into an assetManager, and then display them in my scene.
The general theme of the game revolves around being an operator here on earth searching through radio signals to try to find life in space. Currently, it involves selecting an area of space, and analyzing radio waves there. With the easy-to-use scene UI, I have the first few bits in place at least.
Now the trick is finding more than an hour here and an hour there to work on this...
First short night of coding left me with a project skeleton, a blank starfield, and a few audio assets downloaded and ready to go.
Based on the ideas I've got, the UI is going to be the trickiest part of this thing. For my last game, Robo-Ninja, I didn't use much of LibGDX's scene UI classes, but I think I'm going to need to this time to get finished in time. If they work well, and if I can get the skins stuff figured out, I might have a chance at finishing.
We'll see.
I've started a bitbucket repository for this (yes, bitbucket, not github. I prefer it for the free private repositories), at https://bitbucket.org/gauauu/lifeinspace so that you all can see my horrible code :)
Fun! I thought I had some great ideas for Life in Space, but once it came down to it, I decided they were boring. I've spent the last couple hours sitting on the couch, watching terrible made-for-tv Christmas movies with my wife, pretending to be brainstorming.
Actually, I finally came up with an idea! I think I'm going for a short story/experience game based on the idea of searching for life in space from Earth. I'm pretty happy with the idea, but I'm nervous about the scope. I'm already unsure that I'll have to time this month to finish, and the scope of this game is a little bigger than I had originally planned.
We'll see what happens!
Hi, I'm Nathan, a middle-aged dad from the midwest USA. Been programming my whole life, been interested in hobby game development the whole time. (Spent awhile doing Gameboy advance homebrew, then recently released an Android game with LibGDX). Honestly, between work, family, etc, I'm not sure if I'll have time this Christmas season to complete my jam game or not, but I'm going to try.
If so, I'll probably end up reusing a lot of code from my most recent Android game, including using Tiled for any map development, and hopefully grab plenty of assets from OpenGameArt.
Regardless, I'm excited to see what the rest of you come up with!