kieranhj wrote:Without wanting to trigger a mega-thread, VectorEyes & I were discussing what an Exile 2 might look like, perhaps if it was Master only... or whether the original game is considered the beautiful pinnacle of 6502 game engineering (on the BBC platform at least?!) Not that I am volunteering to code it mind..!

It'd definitely have to be something special which pushed the machine to its newly defined limits. For me, Exile is such a masterpiece of engineering and design, I'd hate to trample on that legacy with a substandard sequel. Definitely a high bar.

kieranhj wrote:That's an interesting idea, whether it might be possible to run the physics simulation / object update on the scond processor to speed up the game itself. Might be more challenging to divide the work as clearly over the Tube as Elite, say.

Yes, that's been my thought on how to create a worthy sequel: a 6502 second processor version where the parasite runs the game code, physics simulation, map generation, etc, and the host is demoted to a sprite plotting workhorse and sampled sound machine. This way you could have more intricate maps, more graphics, more advanced behaviour, and physics handling in parallel with screen refresh.

kieranhj wrote:In terms of having extra RAM, anything on the host side (or SWRAM perhaps) could be used to store sprites in 4bpp (MODE 2 native) rather than 2bpp which ~may~ speed up the screen plotting routines (although no guarantees as Exile code is tighter than tight.)

Remember, Exile uses the colour changing aspect of the sprite routine regularly in gameplay, for highlighting objects when damaged, for the teleport effect, and even just for graphical diversity.

VectorEyes wrote:One could imagine things like Thrust-like carrying heavy objects, different densities of fluids, all kinds of stuff, but I wonder whether they'd really improve the gameplay or not.

I like the sound of that!

sbadger wrote:I've to have also been thinking about a) chaning the seed for a new map

There is no seed! Just a big complicated function of x,y!

sbadger wrote:When originally designed do you think the guys had some sort of editor to specify forced and clear areas on the map? If we had something like that, creating new puzzles scenarios would be a doddle.

I imagine they had a program a little bit like the one I wrote (but which ran the full algorithm, allowing them to see all the tunnels, caverns etc). And they just kept tweaking the many parameters of the algorithm until it landed on something they could imagine working with. It seems hard to believe that they arrived at this by designing the function with any rigour - it's just so complicated. That said, I'm still not 100% clear how they managed to get the mapped bits done.

sydney wrote:As a kid I remember daydreaming about a fully 3d version of Exile, much like Doom - before Doom existed.

Yes, I can imagine it looking beautiful in 3D, though the gameplay kinda lends itself more to a 2D side on view (with the emphasis on vertical shafts and tunnels). A 3D version would need to be very well designed, in order to keep the 3D as little more than a visual gimmick. I can imagine it working with a fixed direction camera, where you could still move in/out of the screen, but where most of the movement was horizontal and vertical.

Rich Talbot-Watkins wrote:Yes, that's been my thought on how to create a worthy sequel: a 6502 second processor version where the parasite runs the game code, physics simulation, map generation, etc, and the host is demoted to a sprite plotting workhorse and sampled sound machine. This way you could have more intricate maps, more graphics, more advanced behaviour, and physics handling in parallel with screen refresh.

If the target platform was super-limited to the Master Turbo, you could also use both screen buffers to allow for single pixel horizontal scrolling (offsetting one screen one pixel from the other). Combined with the normal 'rupture' vertical scrolling, that'd be quite a unique Beeb experience. Of course, that'd also give you a guaranteed extra 64k of RAM too, which could really pack in a lot of sound and graphics!

Looking at the function determine_background, &1715, we can breakpoint there, say in b-em and then force lookups of the content of any game tile by setting &95 = square_x, &97 = square_y.

The useful button is at x=e3,y=bc. This location returns a game tile value of 3. 3 happens to be a special value that makes the engine look up a background object in a hash table of sorts, with the x co-ordinate mixed in. For game tile value 3 at x=e3, this leads to a data pointer value of 6e, (stored in &bd) and a type pointer value of 4c (stored in &be).

Ok, let's look up the echo of the button, at x=e3,y=9c. Ah, this also returns a game tile value of 3, again a special value causing a background object lookup. Since the value is the same, _and_ the x co-ord is the same, we'll get the same data and type pointers that we got earlier, because the result is essentially f(tile value, x). So two map tiles reference the exact same memory locations for a single button.

My mental model of this is that it's essentially a compression artifact.

I'm not 100% sure but I think it might be an optimization to save a few bytes here and there. This trick would enable eliminating checks for "was the result the NULL object"? Who cares -- just write the object slot, even if it's 0, and slot 0 can just be a dummy slot that can be trashed arbitrarily.

Cheers
Chris

I've been digging into Exile again, from the tables in the disasm, how is the y coord derived from the bo tables

background_objects_n, i.e. x, handler, data and type, where does the y comes from?

Both coordinates come from the map generation routine. Look at determine_background. It calls calculate_background, which returns an 8-bit value: two flip flags (top 2 bits), and the so-called square sprite (bottom 6 bits - see the table above background_prite_lookup).

If the square sprite is less than 9, then the game tries to find the X coordinate in the object X lookup table. That table isn't used to find the X coordinate - it's actually a list of X coordinates of squares with types less than 9, and it's searched linearly to find out what needs to go in that square. Then I guess the index is used to look up in the other background objects tables? - haven't got that far yet!

(The table is actually 9 tables in 1, with the square sprite used to select the range to search - the range is from background_objects_range[sprite-1] to background_objects_range[sprite]. So it's kind of like a chained hash table.)

For example, the upper door in your ship, which is at ($9c,$3c): calculate_background produces a value of $40 for this square - square sprite $00, vertically flipped. So look in range 0 of the X lookup table ($00...$1c), and find objects_x_lookup[$0e]==$9c.

Haven't got any further than that yet, but I did notice that the actual object that ends up in the square can be set up in code. For example, the door in your ship: its handler is 3 (see the background objects table). Look that up in object_handler_table and find handle_background_door, which looks like it calls pull_objects_in_from_tertiary_stack with A=$3c (amongst other possibilities), presumably creating a door. (See the object handlers comment - $3c = horizontal door.)

I'm Exile'd out for now, but I've pushed a few more comments to GitHub.

--Tom

P.S. interestingly, the disassembly has a different value in the background_objects_range table, which I changed when first making the code buildable so that the result was identical to the STH copy. I wonder which one is correct here.