šŸ” Chicken Invaders 1 Remastered #08

Alright, time to look at some code.

Argh, my eyes! Well, a few things quickly become painfully apparent:

  • I wasn’t really into ā€œcompilation unitsā€. Everything is dumped into one big source file. (*)

  • I did not believe in private members. Everything is public. In fact, there’s not a single mention of the private keyword anywhere in the CI1 code. (**)

  • I didn’t know or care about constructor member initializer lists ( Constructors and member initializer lists - cppreference.com ). Everything is manually initialized with assignments. (***)

  • No spaces after commas or assignments. (****)

  • There’s a pointer to UVE being passed around literally everywhere. I guess back then I didn’t believe in global variables either. (*****)

* Well, it’s ā€œbigā€ by 1999 standards. CIU has a couple of files around the 10K line mark – but there’s a good reason for that, I promise!

** To be fair, I do see a few private keywords in UVE’s source code. So I was definitely aware of it. Regardless, there’s a good case to be made for making everything public by default, especially for small projects, because it minimizes the amount of boilerplate/scaffolding code (namely, ā€œgetterā€ and ā€œsetterā€ functions). Certain very prominent programmers still advocate the ā€œeverything public by defaultā€ approach.

*** This reminds me of the time I was around 10 years old, and I was desperately trying to make a ā€œsliding puzzleā€ game without knowing what arrays were (spoiler alert: I didn’t get very far). Or the time I took part in a programming competition without knowing what recursion was (spoiler alert: I didn’t get very far either). Or the time I didn’t know how heaps work (spoiler alert: I still don’t).

**** I still don’t bother with that – it just slows things down. But nowadays at least I’m using automatic code formatting, which takes care of that for me.

***** Although there’s some merit to that idea, the programming burden to pay is sometimes too high.

Anyway…

I spend the next few hours furiously hacking away at the code, trying to get it to a compilable state. I’ve already explained more about this stage:

Finally, success! It compiles!

image

A short-lived celebration

I start up a new game, and I am immediately greeted by the following:

image

It turns out that this is an RNG issue. Due to patently bad programming, CI1 sometimes requests random numbers with a negative range, and the CIU randomizer doesn’t handle that case correctly. If you ask for a random number between 0 and 1, you get correct results (always 0, by the way), but if you ask for a random number between 0 and -1, then you get 2 gazillion back. CIU is a much better behaved game and never asks for negative ranges, so this issue remained dormant for years. But it’s been exposed now!

I spend some time very carefully fixing the bug in the CIU randomizer to make sure it still generates the same numbers (otherwise all the randomly-generated CIU missions would change!).

Completely by accident, as part of the debugging process, I notice there is something strange with the smoke/fire trails of asteroids: The first puff of smoke is always spawned at (0,0), which for CI1 is the top-left of the screen, regardless of where the asteroid is.

A bug?

Incredulously, I load up the original game to check. And sure enough, there it is:

image (*)

* I couldn’t capture the screenshot at the exact right time, so this is only a re-creation.

Show of hands – did anyone ever notice this? I certainly didn’t.

I check the code and it’s a case of ā€œincomplete initializationā€, very similar to what has been plaguing CIU (and previous episodes) for many years whenever you join a multi-player game while it’s paused.

The fix is very simple, but I mull over whether this should be actually fixed. I’m hesitant to change code behaviour, both as a matter of principle, and both out of fear I’ll miss some delicate dependency and inadvertently break something in the process.

I finally decide that yes, it will indeed will be fixed. So there you have it, (at least) one way in which CI1 is better than CIU! You’re welcome.

Another bug?

I also notice that some bullets are not facing the correct way:

image

This turns out to be an incompatibility in CI1’s wrap(x,a,b) function, which wraps number x between a and b inclusive, and CIU’s corresponding function, where b is actually excluded from the range. I stupidly thought I’d just delete the old function and let the new one take over, because – hey, newer function, right? It’s got to be better!

Well, now I know better. Mental note: Do not touch the code unless absolutely necessary!

Keyboard/Joypad/Mouse control

Having addressed the immediately apparent problems, I now decide the next thing I should tackle is adding more input methods to the game. I spend some time wiring up controls for keyboard(*), joypad and mouse. Thankfully I’m using a gutted CIU codebase, which has comprehensive controller support, so the process is relatively painless…

… with one exception: I spend an embarrassingly long time trying to get the spacecraft to stop exactly where the mouse points. In the original game, your spacecraft does not stop instantly, but rather decelerates and gradually comes to a stop, and I wanted to preserve this behaviour even when using the mouse.

image

ā€œBut the stopping distance is simply the sum of the speed/acceration arithmetic series! There are formulas for that! Look it up! You even used that same formula to make spaceships decelerate properly at the end of a trip in CIU! It’s easy!ā€

Nope. Still had to calculate it iteratively :roll_eyes:

* As a side-effect, I discover CIU has been accidentally including keyboard controls for two players all this time .

High score entry

High score entry was one of the first things to be commented out while trying to get the code to compile. I originally had no intention of putting it back in because it seemed to be slow, inelegant, and altogether a relic from another era. Not to mention it would be a hassle to get working, because it’s specialized code. It would be much easier for the name to be automatically filled-in from the player’s profile (as is done in CI2-CI5).

What eventually changed my mind is that there are two players that might need to enter different names. And also, of course, preserving the original as accurately as possible.

image

An interesting annoying thing about this screen is that the boxes containing the letters are not actually bitmaps, but they are drawn ā€œon the spotā€ using GDI (ugh). There’s no good way to modernize this, so I’ll convert them to actual bitmaps.(*) For now I’ve just used some placeholder graphics – I’ll revisit this when it’s time to work on the GUI.

image

* This is much cleaner design, anyway, and much more consistent. I don’t know what I was thinking when I used GDI… I’ll chalk this one up to inexperience.

Back-pedaling

Yeah, that’s been thrown in the garbage. It didn’t work properly and it broke compatibility for very little benefit. I’ve decided to kick this particular can down the road to my future self when (if?) it’s time to re-master 1X games (such as Piggly or Loco). I’m going to hate myself then, I’m sure.


Next part in the series

Start at the beginning

34 Likes

One can only wonder what InterAction Studios could accomplish while using other game engine.

Have you ever thought about a little side project like that? (I personally recommend waiting for Godot 4.0 since it will be a massive improvement and you don’t need to get yourself locked to Unity or Unreal ecosystems.)

2 Likes

But how? How can the game predict when you’ll stop using your mouse so it decelerate? Otherwise, it’ll spend time decelerating away from your mouse.

1 Like

That reminds me of that atrocious mouse movement from CI2 versions before 2.60. If the mouse was moved very slowly, the spaceship would fly around.
It was really inconsistent and in my opinion, mouse players shouldn’t suffer from deceleration. Spaceship should stop immediately as soon as the ship stops moving.
I’d say this feature should be kept if you play via keyboard, I see more sense in that.

3 Likes

Idk why ,but remastering this game has quickly turned to hard work and disaster.
(And the discovery of thousands of buged and unused code in ciu)
Seems like remastering this game will be a remaster to ciu instead lol

and as for the RNG error and calling your programmings and code bad.
You certainly didn’t know that much abt programming in 1999.
but now you’re keeping thousands of lines of codes and a server and running an online game.
So yeah you became a better programmer than the one you were 24 years ago .
You’re good iA you showed us all the best of chicken hunting games (and the authentic hero which all he wanted in life was a burger and some fries)
The point is you kept us together at the best games and gave us hope (while all that we did was crash and hack and destroy your games whenever it was possible) but now it’s time we give you hope. You’re a good programmer. Your the best iA no matter what happens you made ciu (presumably the only game I play now)
The last 4 years proved your success
We saw ciu

We saw bugs

We saw hackers

We saw friends crashing servers

But no matter what you kept everything together

And now it’s time you continue that success.
With our support.
Your programming.
And some random people who expose bugs and crash servers (iIfireIi)
Together we’ll continue interAction studios legacy (Idk why didn’t I right that in the last 4 years recap but I’m not retyping all of this .I’m literally out of feelings to write lol)

Keep it on iA😁

2 Likes