Side Scroller 95
I haven’t been doing much work on new projects recently. Mainly, I’ve been perusing my archives looking for interesting things to play around with. Some of them needed some light work to get working again but really I just wanted to experience them.
I did come across one old projects which I’ll talk about here: a game I called Side Scroller 95. And yes, the “95” refers to Windows 95.
This was a remake of Side Scroller, a QBasic game I made back in the day. Having played around with Delphi programming after a while, and finding a bunch of DirectX 7 components, I set about recreating this game. I’m not sure why I decided to remake this game vs. making something new. Was it because it was simple enough to try, or I found the levels interesting? Maybe? I can’t really say.
Anyway, there wasn’t much to this game from the beginning. All the movement was cell based, with the usual assortment of solid tiles, hazards, and keys and locks (no pickups though). I eventually added a simple enemy as well: a robot which just went from left to right.
This project really showcases my crappy art skills at the time (I wish I could say they improved, but that would be a lie). The tiles and sprites were creating using MSPaint. This was back in the day when MSPaint was actually quite usable for pixel art, where drawing a rectangle actually rendered a rectangle then and there, rather than product an object which could be moved around (it’s just not the same now). The backgrounds were made by making gradients in Microsoft Word, taking a screenshot, and cropping them. And the sound effects were taken from the PC version of Metal Gear Solid (the WAV files were just sitting there on the file system).
The game itself is pretty unremarkable, although I would say that one
attribute that I really enjoyed doing is adding level scripts. These
were Pascel scripts — interpreted by a Delphi control I found — that
intercepted events, such as triggers or timeouts, and modified the level
in some way. This was done late in the project, so it wasn’t used much,
but it did make for some unique level-specific elements in the later
levels. An example of one of the level scripts is provided below. This
added platforms which ascended one cell at a time when activated. I
forget most of what the built-ins did but I believe the OnActivateX
hooks fired when a switch was triggered and the OnTimedEventX
fired
when a timer elapsed.
unit LevelScr;
uses SSUTIL;
const
INT_STX = 0;
INT_STY = 1;
INT_EDX = 2;
INT_EDY = 3;
INT_CURX = 4;
INT_CURY = 5;
procedure LevSetupMove(sx, sy, ex, ey: integer);
begin
SetStackInteger(INT_STX, sx);
SetStackInteger(INT_STY, sy);
SetStackInteger(INT_EDX, ex);
SetStackInteger(INT_EDY, ey);
SetStackInteger(INT_CURX, sx);
SetStackInteger(INT_CURY, sy);
end;
procedure OnActivate1(tag: integer; ison: boolean);
begin
case tag of
1: LevSetupMove(6, 9, 6, 5);
2: LevSetupMove(18, 9, 18, 4);
3: begin
LevSetupMove(20, 19, 20, 16);
Level.SetTile(21, 18, 52);
end;
4: LevSetupMove(11, 23, 11, 19);
5: LevSetupMove(10, 23, 10, 17);
6: LevSetupMove(9, 17, 9, 15);
7: LevSetupMove(9, 15, 9, 13);
8: LevSetupMove(9, 13, 9, 11);
end;
SetupTimer(1, 2, 1, true);
end;
procedure OnActivate2(tag: integer; ison: boolean);
begin
case tag of
1: LevSetupMove(20, 20, 20, 16);
end;
SetupTimer(2, 2, 1, true);
end;
procedure OnTimedEvent1(event: integer);
var cx, cy: integer;
begin
cx := StackInteger(INT_CURX);
cy := StackInteger(INT_CURY);
if ((cx = StackInteger(INT_EDX)) and
(cy = StackInteger(INT_EDY))) then
begin
ResetTimer(1);
end
else
begin
Level.SetTile(cx, cy, 12);
cy := cy - 1;
Level.SetTile(cx, cy, 13);
SetStackInteger(INT_CURX, cx);
SetStackInteger(INT_CURY, cy);
PlaySound(11, false);
end;
end;
procedure OnTimedEvent2(event: integer);
var cx, cy: integer;
begin
cx := StackInteger(INT_CURX);
cy := StackInteger(INT_CURY);
if ((cx = StackInteger(INT_EDX)) and
(cy = StackInteger(INT_EDY))) then
begin
ResetTimer(2);
Explode(cy, cx);
end
else
begin
cy := cy - 1;
Level.SetTile(cx, cy, 0);
SetStackInteger(INT_CURX, cx);
SetStackInteger(INT_CURY, cy);
PlaySound(11, false);
end;
end;
end.
One other hallmark of this project was completely gutting all the hard-coded logic and moving it into a game definition file. I build a pretty simple “game designer” tool which managed all the artwork, tile and sprite definitions, and also had custom logic implemented using that same Pascal interpreter I was using for the level scripts. I never used it for anything than the “Side Scroller” game, apart from a recreation of the File Platform game I also built way back when.
Again, nothing about this was remarkable, and for a long time I had no way to get this working. But thanks to Whisky I managed to launch this for the first time in ages and have a play. I don’t know when I’ll be able to do so again, nor whether it’s a good use of my time to try, so I recorded some screencasts of the gameplay which you can see here:
- The Test Level Set — used to test the level script feature.
- The Additional Level Set — these were the levels that really made use of level scripts, including the one listed above.
The desire to move away from cell-based movement and physics continued my drive in making platform based games in Delphi. I eventually managed to build such a game, which I will talk about once I can get it working again.