Jump to content

Karl's Blog

  • entries
  • comments
  • views

Penult Timing

Karl G


I've been writing a few blog entries with semi-technical notes about the innards of my WIP Ultima-style game. In this one, I describe how I handle all of the game's tasks without running out of CPU time.


With many Atari games, especially ones that do not make use of a coprocessor like the ARM, limited CPU time for game logic can be a challenge. Since Penult is a turn-based game, timing isn't as critical for many of the game's tasks.


I have divided all of the game's tasks into tasks that need to run every frame, and tasks that can run once every 4 frames. The tasks that can run every 4 frames are further divided into tasks that run before the visible screen is displayed (vertical blank), and tasks that run after the visible screen is drawn (overscan).


For the most part, after breaking up the tasks like this, running out of CPU time hasn't been much of an issue. A big exception was the map loading and visibility code. Every frame, whatever portion of the map is loaded into RAM is displayed during the visible screen. Every 4 frames, the currently-visible portion of the current map is loaded into RAM (which may or may not have changed since last time). The tricky part is that once these have been loaded in RAM, the visibility code must be run to blank out tiles that would not be visible from the current position. Both of these tasks must be done before the next time the visible screen is displayed:


Map before visibility blanking:




Map after visibility blanking:




The denser forest tiles should obscure tiles behind them, and hide the city from view from that position.


Here's a broad overview of game tasks, and when they are performed:


Tasks Before Visible Screen (Vertical Blank):

  • All frames: Set P0 and P1 positions, Update wind, Sound / music updates
  • Frame 0: Check turns and hunger, check for encounter, set status / text fields
  • Frame 1: Line of sight code or combat logic or stat screen stats
  • Frame 2: Menuing, button, joystick, movement
  • Frame 3: Currently nothing


Tasks After Visible Screen (Overscan):

  • All frames: Currently nothing
  • Frame 0: Stat screen base or combat arena or load town/outdoor map
  • Frame 1: Joystick delay / repeat
  • Frame 2: Process map triggers
  • Frame 3: Load ship and other movable tiles



Recommended Comments

The engine is looking really good, and I like how you've broken up the tasks by frame. I'm not as disciplined, and tend to do frame task-balancing only when I've started to hit issues. :)


There's a trick I do on the 7800 for gauging the relative weight of routines for balancing - since most game code is running during the visible screen, you can change the background color at the start and end of routines, which shows how many "lines" of CPU time you've used. It's a shame there's not something similar to be done on the 2600. You could do it in principal I guess, if emulators showed all of the overscan and vblank lines, and you disabled blanking.

  • Like 1
Link to comment

That does sound like a useful trick. I can figure it out with the debugger, but having a visual would sometimes be handy. 

Link to comment
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...