Skip to content

Latest commit

 

History

History
291 lines (225 loc) · 13.2 KB

File metadata and controls

291 lines (225 loc) · 13.2 KB

Stealth Runner

Stealth Runner Stealth Runner is a third-person open-world action game for the TI-99/4A home computer.

Features

  • Pre-rendered graphics.
  • Smooth motion-captured animation (30 fps).
  • Game world with a consistent global state (4096x4096 pixels).
  • Pixel-precise omni-directional scrolling.
  • Sound and speech.
  • Entirely written in TMS-9900 assembly code.
  • The source code!

Screenshots

Screenshot 1 Screenshot 2 Screenshot 3 Screenshot 4 Screenshot 5 Screenshot 6 Screenshot 7 Screenshot 8 Screenshot 9 Screenshot 10 Screenshot 11 Screenshot 12

You can also watch a video of the intro and the first section of the game on YouTube.

You're welcome to join the Stealth Runner thread at AtariAge.

Requirements

Most conveniently, if you want to run the game on a modern platform:

  • A TI-99/4A emulator, such as Mame, Classic99, JS99er, or MiSTer FPGA.

Alternatively, if you want to run the game on the original hardware:

  • A TI-99/4A home computer,
  • a programmable ROM/RAM cartridge, with about 1.8 MB of space, such as the Pi Pico PEB expansion or the Yellow Board cartridge,
  • a 32K memory expansion (optionally an internal one),
  • a speech synthesizer (optional),
  • a Mechatronic mouse (optional).

Downloading

You can download the latest binary from GitHub.

Building

If you want to build the game yourself, you'll need a couple of tools. These are readily available for Linux distributions, but other platforms may work as well.

  • The 3D animation package Blender (Debian package blender), for rendering the player avatar and the objects in the game world.
  • The image toolkit ImageMagick (Debian package imagemagick), for processing animation frames.
  • The video converter ffmpeg (Debian package ffmpeg), for processing sound files.
  • The command-line tool xxd (Debian package xxd), for converting simple hex source files to binary files.
  • My Video Tools for the TI-99/4A, for computing speech coefficients, for converting music, and for creating the intro video.
  • A Java development environment (Debian package openjdk-17-jdk, for example), version 14 or higher, for the video tools.
  • The xdt99 cross-development tools, for assembling the code.
  • A Python 3 runtime environment (Debian package python3) for the cross-development tools.

On Linux, you can then run the build script:

./build.sh

Alternatively, you can run its commands manually.

You'll then have

  • a raw cartridge ROM file out/romc.bin, which is suitable for physical cartridges and for emulators like Classic99 and JS99,
  • a cartridge file out/StealthRunner.rpk, which is suitable for emulators like Mame.

Running

The easiest way is to run the ROM in an emulator, such as Mame (version 0.278 or higher).

On Linux, you can run the script to launch Mame with the proper options:

./run.sh

Alternatively, you can run the Mame command manually. The game targets an NTSC system, with a display at 60 Hz. You can optionally enable the faster internal memory expansion, to improve the frame rate at busy moments (Scroll Lock, if needed, to get in Mame's UI mode, and then Tab > Machine Configuration > Console 32 KiB RAM upgrade (16 bit) > On).

With the computer or emulator running, at the TI-99/4A home screen:

  1. Press any key.
  2. Press 2 for "STEALTH RUNNER".

You'll get the intro. You can start the game at any time by pressing Space. The goal of the game is to find and reach the final target cross in the world, evading or destroying enemy devices. You may encounter:

Target Target (save point).
Stone Stone.
Medkit Medkit.
Battery Battery charge for electromagnetic pulses.
Grenade Grenade.
Mine Enemy mine.
Drone Enemy drone.
Turret Enemy gun turret.
Launcher Enemy shell launcher.

You can control your avatar with the keyboard and optionally a Mechatronic mouse:

Q Turn left.
E Turn right.
W Move forward.
S Move backward.
A Strafe left.
D Strafe right.
Shift Speed up from walking to running.
X Swap the current weapon (stone, electromagnetic pulse, grenade).
Enter Fire the current weapon.
Ctrl Apply a medkit when your health is low.
Mouse Turn.
Mouse button 1 Fire the current weapon.
Mouse button 2 Swap the current weapon.
6 = Proc'd Pause/unpause the game.
7 = Aid Restart at the most recent save point.
8 = Redo Start a new game.
9 = Back Return to the game title screen.
= = Quit Return to the computer title screen.

When you die, you can still press Aid, Redo, Back, or Quit.

You can exit Mame by pressing Scroll Lock (if needed, to get in Mame's UI mode) and then Esc.

Tips

  • Try to reach the save points (yellow crosses) in the world. When you die, you can restart at the most recent save point by pressing 7 (= Aid).
  • The color of your avatar indicates your health/stamina. Your stamina decreases when you're running and when you get hit by enemy fire. Your avatar will stop running whenever your stamina gets too low. You can recover slowly by standing still or walking quietly, or you can heal instantly by applying a medkit (with Ctrl).
  • Ennemies react to noise. You may be able to pass them undetected by walking quietly (not running).
  • You can lure enemies away from you by throwing stones.
  • You can carry any number of medkits and weapons that you can find.
  • The game doesn't show an overview map. The layout of the world is relatively straightforward, but if you struggle getting your bearings, you can peek at the image that defines the game world. You can generate the corresponding legend with a script for bash and ImageMagick.

Known issues

  • The video processor of the TI-99/4A can only display 4 sprites per row of pixels. As a result, objects that are rendered as sprites may (temporarily) appear clipped.
  • Due to tricky timing issues in communicating with the speech processor, speech snippets may occasionally come out garbled.
  • Mouse movement may get inverted at random times during the game. It's probably easier to use the keyboard for now.

Technical background

The game tries to push the envelope of what is achievable on the TI-99/4A. Can we deliver interactive, motion-captured, pre-rendered graphics, with the help of freely available modern-day resources?

The implementation builds on my experiences with streaming graphics, sound, and speech in my Bad Apple demo for the TI-99/4A. The demo is linear; this game is fully interactive. The general strategy is still to preprocess resources to efficient custom formats.

Graphics

The player's avatar and its motion-captured animations originate from Mixamo. They have an amazing collection of 3D character models and motion-captured animations, which can be downloaded for free.

I've imported the "SWAT" character and animations in the open-source animation package Blender. I've additionally created static 3D objects. The build process runs custom python scripts in Blender to render the character and the objects. Each motion-captured animation has between 20 and 31 frames and is rendered from 16 viewing angles.

Further python/bash/java scripts/programs massage the resulting images. I'm using the open-source toolkit ImageMagick to reduce the resolution and the number of colors, since the TI-99/4A supports a fixed resolution of 256x192 pixels and a fixed palette of 16 colors. The scripts eventually convert the images to efficient, custom file formats for the game.

Speech

The speech in the game is generated with AI text-to-speech conversion (on OpenAI.fm). It's an effective way to get consistent and crisp sound files. I've then converted these files to speech coefficients for the TMS5200 speech synthesizer of the TI, with my own open-source Video Tools.

Music

The music originates from freely available MusicXML files. Notably, I've picked a segment from Mozart's piano concerto No 20 (K466) and converted it to a format that is optimized for the TMS9919 sound chip of the TI, again with my Video Tools. The conversion tool tries to squeeze all parts, bars and chords into the 3 available sound channels.

Sound

I've manually created some simple sound effects for the sound chip of the TI. They are hard-coded in the game's assembly code.

Video

I've created the short introductory animation sequence with Blender, ImageMagick, and my Video Tools, building on the Mixamo models and the MusicXML file.

Game world

The game world is represented by a plain image file. A custom tool again converts it to optimized formats that are then included in the application.

Game code

The game's assembly code ties together all resulting assets. For low-level code, it is still quite readable, thanks to macros and comments, and thanks to the excellent xdt99 cross-development tools. The major challenge is to efficiently stream graphics to the video display processor. The code tries to update just the changes between frames: characters and patterns of the landscape, characters and patterns of the player's avatar, positions and patterns of the sprites. Standard 16x16 pixel sprites are combined into larger sprites. They are cached in the available space in video memory and swapped in when necessary. The most performance-sensitive code is run from the computer's 256 bytes of 16-bit scratchpad RAM. The game interleaves all computations between even and odd frames at 60 NTSC video frames per second, resulting in updates at 30 frames per second.

The source code contains a collection of include files that can be more generally useful for game development. They provide convenient and efficient support for graphics, sound, speech, and keyboard/mouse input.

Label

If you're creating a physical cartridge for the game, you can apply ti99iuc's nice label:

Label

License

Stealth Runner is released under the GNU General Public License, version 2.

Enjoy!

Eric Lafortune