Author Topic: Design history: Hi-res physics  (Read 83 times)

0 Members and 1 Guest are viewing this topic.

Offline Simon

  • Administrator
  • Posts: 2530
    • View Profile
    • Lix
Design history: Hi-res physics
« on: December 04, 2018, 12:49:04 am »
Hi,

Double resolution

Lemmings 1 and Lemmings 2 were written for 320x200 VGA mode. The playing characters are 8 or 9 pixels high, walk ahead by 1 per frame, and builder bricks are 1 pixel high.

Lix is double-resolution: Characters are about 17 pixels high, walk ahead by 2 hi-res pixels, and builder bricks are 2 pixels high. More precisely, physics work with 2x1-pixel-chunks. All lix' x-coordinate is always divisible by 2. Only the y-coordinate may be any integer. A 2x1-chunk of land counts as solid as long as at least one of its two pixels is solid.

Where does this concocted rule come from?

In early 2003, I scripted levels for the freeware game Gravity Strike, this ran with hardcoded 640x480 fullscreen. In the early 2000s, CRT monitors were widespread and could display any resolution sharply -- up to a point. But every monitor could display 640x480, thus Gravity Strike's author decided to hardcode this size.

I wrote GS Lemmings, a Lua script that ran in Gravity Strike, removed everything that the game normally provides (spaceship, terrain, enemies, status panel) and instead loaded my own graphics and ran my own logic. This is the birth of double resolution: It was easiest to work with what I had.

In Lua, apart from numbers, everything is a reference type, everything is garbage collected. I had no idea what was happening under the hood. Would arguments be passed by value or by reference? What is the difference between calling functions object.func() or object:func()? No idea. Programming was magic. If it failed, I would guess and re-try. I would never search the web for help because I found the technical explanations hard to understand. (Solution: object:func() is equivalent to object.func(object)).

In 2006, I finished my civil service -- back then, it was mandatory for every male German to either serve in the military or work civil service for 9 months. I had some time before university started in fall 2006. What to do?

I learned C++ and began the work on L++, a Lemmings variant with hardcoded 640x480 fullscreen resolution. Why would I do that? It worked in Gravity Strike, and I still had a CRT monitor that could display any resolution well. I kept my rule that the tiles could be anything and need not stick to 2x2-blocks. I would not upscale. I would load the tiles as they came from disk. That was easiest.

The 2x1 physics instead of 1x1 come from the desired walker speed. It was simpler to move always by 2 horizontal pixels than to write a basic walk action for 1 pixel, then call that twice per frame. The walk cycle would look at two pixels and deduce from them together whether the 2x1 chunk was air or solid. I didn't expect any odd cases from the rule.
Of course, there are odd cases (I should link the example gifs).

L++ became Lix in 2010 and got ported to D in 2015. Like Theseus's ship, all code, graphics, etc., got replaced over the years, but really, 2006 L++ was the first version of Lix.

With my own game project at 640x480 fullscreen hardcoded, I spent considerable time on choosing my first laptop in 2007. I wanted 4:3 aspect ratio for my laptop screen, but that was getting unpopular. Laptop computers were booming, and widescreen displays had gotton common. I loved 4:3, why would anybody want 16:10? Documents, websites, code, etc., everything is vertical, but most importantly, 16:10 TFT displays would blur at 640x480 hardware fullscreen.

Lix/L++ is now 12.5 years old and programming been my longest-standing hobby. Now, Lix supports any screen resolution, windowed or fullscreen. The user interface scales smoothly, a major design goal during the 2015 rewrite.

Even with the user interface resolution decoupled from the physics resolution, Lix still has 2x1-hi-res-physics. I don't like how confusing the 2x1-block rule can be. But it has been so deeply ingrained since the beginning. It allows for more graphical details on tiles. On the other hand, it forces tiles to have more details to look good.

tl;dr: It was easiest because of the hardcoded 640x480 resolution in the early versions. And now too much depends on it to get rid of double resolution.



Passage of time

More rambling, because I'm in the mood.

I feel like time is passing much quicker now. In 2003, GS Lemmings was released with 20 levels after maybe 2 months of work, with some bugs of course, some crashes, some reliance on 60 FPS -- Yes, the game would skip some physics logic, but not all physics logic, when the machine was slow! Horrendous bug! -- but it worked well enough to play. The 2-3 regulars on the Gravity Strike forums loved it.

Where GS Lemmings took 2 months, L++ required 3 years before I felt ready to post it on Lemmings Forums including networking mode. A more complicated feature, sure, and I wrote the game engine from scratch instead of relying on a host game.

It's been nearly 4 years since I started the rewrite to D in early Feburary 2015. I'm very very happy with the rewrite, I've pushed the game further, and I'm supporting different operating systems better than ever before. But are there killer features in D Lix that weren't already there in C++ Lix? Did the fundamental game take 2-3 years to implement in 2006 to 2008, and the 10 years after it has been only polishing?

Sometimes, I miss the days where I would implement buggy crap with trial-and-error, but have something cool to show after minimal development time. The 15-year-old kid inside me wants to feature-bloat on some side project. And the 5-year-old inside me wants to play that and get even more wild ideas.

When time passes linearly, memories increase only logarithmically. You remember so much from when you start a new activity. But then you get proficient, and you don't remember as much when you're performing by routine.

Consider the time after my civil service. I learned a good chunk of C++ and wrote a prototype-ish game, L++ with some singleplayer, in half a year. Then, I had nearly no other hobbies, obligations, or girlfriends, and could focus fulltime on L++. Now, 12 years after, I had comparable time after finishing the PhD, but I haven't started a new hobby in that time. But I already have so many hobbies -- games, Lemmings Forums, speedruns, tech projects -- that I've enjoyed in that time. They merely generated less impactful memories than starting a new hobby typically generates. That's why time seems to fly quicker.

At least I've finished xmas2018 on time. :lix-grin:

-- Simon
« Last Edit: December 04, 2018, 08:04:34 am by Simon »