Jump to content
IGNORED

Hellway 2 Players Edition


Recommended Posts

Hellway 2 Players Edition


I am opening this topic as a personal development blog, of a derivative work of Hellway. The final objective is to make a true multiplayer version of Hellway, with each player having a consistent view of the world and their cars interacting. This is possible because the game state of Hellway is deterministic. It is like the screen is just a view of a world, and completely consistent regarding position and time.

I am doing this by drawing 2 screens, alternating between left and right side each frame. From all my tests, the game is perfectly playable and a constant 30hz flicker totally ok. I am planning to evolve the game physics for the 2 players every frame, so the game keep the same control responsiveness.

To make this solution work, I had to remove one car lane, remove parallax, and remove the end game decimal counters, but the essence of the game is fully kept.

The way I shift everything is quite unusual, for the sake of simplicity I do 10 HMOVE with the value of 8, moving everything half screen, while keeping the relative position of everything intact. The playfield borders I use async playfield, but for the lack of cycles, I just do it once in my 3 lines kernel, I write once, and erase once before it leaks to the other side of the screen, and that explains the border pattern you see.


Since the screen is flickering and the colors have less intensity, dark mode became the default.

I considered making a horizontal engine to avoid flickering, but this would mean to rewrite everything. Each lane currently works as a free vertical canvas area, where any car pattern can be draw. An horizontal engine would have a limited set of patterns, loosing the game identity in the process.

Hellway 2PE does not try to replace the original, which runs without flicker, have detail statistics, border effects and a plus cart version. It tries to run well enough and allow two people to play together, with the trill of the chase and overtake. It is also to be a technical challenge for me to run the 2 games at the same time without additional hardware.

Links:
 

https://github.com/opbokel/hellway2pe (Git Repo)

 

https://github.com/opbokel/hellway2pe/blob/main/bin/hellway2pe.asm.bin?raw=true (Binary, always the latest version)

https://javatari.org/?ROM=https://github.com/opbokel/hellway2pe/blob/main/bin/hellway2pe.asm.bin?raw=true (Javatari link)

 

 

Main Road Map:
 - Use the directional to change car type for each player
 - Process player 2 controller and game state.
 - Collision Part 1, the second player should crash with the environment.
 - Process players relative position.
 - Recreate the hud to display information for both players.

 - Recreate Score screen with relevant information for a 2 players game, without additional RAM usage (currently broken from the removal of decimal counters)
 - Collision Part 2, the player behind crashes.
 - Collision Part 3, a players while invincible by a checkpoint, can "kill" a non invincible player
 - Solve consistence in random game modes.
 - Any other adjustment, fine tuning and feature...

I am trying to answer 2 things with this post:

- Do you think the game still playable at 30hz?
Everybody that can do a quick test (real hardware or not) please post your experience on this early version. Your opinion is much appreciated!

 

- Is it the first split screen game with players interaction? 
After some research I found some example of games, but none of them the players can direct interact. They play the game at the same time and have separated scores and screens, but cannot kill each other, crash into each other or see the other player in their own screen. If you know any game that does this, please post.


Thank you all!
 

hellway2pe.asm_3.png

  • Like 9
Link to comment
Share on other sites

(Technical Post)

The code for car selection I just refactored, as I realize that duplicating all code that have to run for both players will not fit into 4kb. Also would make the code error prone.
As we start processing things for the second player, the code must start using indirect address, offsets, variables etc... so it can run for both players, on the expense of a little bit of additional cycles, which I do have on the blank lines.

The code that sets the player ids based on the direction of the dpad went from
 

SelectCarWithDpad ; Only do it when game is stoped
    LDA SWCHA
    AND #%00010000
    BNE ReadDpadDown
    LDA #0
    STA CurrentCarId
ReadDpadDown
    LDA SWCHA
    AND #%00100000
    BNE ReadDpadLeft
    LDA #1
    STA CurrentCarId
ReadDpadLeft
    LDA SWCHA
    AND #%01000000
    BNE ReadDpadRight
    LDA #2
    STA CurrentCarId
ReadDpadRight
    LDA SWCHA
    AND #%10000000
    BNE SelectOpponentCarWithDpad
    LDA #3
    STA CurrentCarId
SelectOpponentCarWithDpad ; Only do it when game is stoped
    LDA SWCHA
    AND #%00000001
    BNE ReadOpponentDpadDown
    LDA #0
    STA OpCurrentCarId
ReadOpponentDpadDown
    LDA SWCHA
    AND #%00000010
    BNE ReadOpponentDpadLeft
    LDA #1
    STA OpCurrentCarId
ReadOpponentDpadLeft
    LDA SWCHA
    AND #%00000100
    BNE ReadOpponentDpadRight
    LDA #2
    STA OpCurrentCarId
ReadOpponentDpadRight
    LDA SWCHA
    AND #%00001000
    BNE CallConfigureCarSprites
    LDA #3
    STA OpCurrentCarId
CallConfigureCarSprites
	...

Was compressed to:
 

;Tmp0 Current SWCHA mask, will be right shifted 4 times
;X player 0 or 1
SelectCarWithDpad 
    LDY #3
SelectCarWithDpadLoop
    LDA SWCHA
    AND Tmp0
    BNE ContinueSelectCarWithDpadLoop
    TYA
    STA CurrentCarId,X
ContinueSelectCarWithDpadLoop
    LSR Tmp0
    DEY
    BPL SelectCarWithDpadLoop
    RTS

SelectCarWithDpadCall ; Only do it when game is stoped
    LDX #0 ; Player 0
    LDA #%10000000 ;SWCHA Mask, it ends the call in the correct value for Player 1 call
    STA Tmp0
    JSR SelectCarWithDpad
    INX ; Player 1
    JSR SelectCarWithDpad


This type of thing must be done to all areas where the code must run for both players.

 

Edited by Octavio Pinho Bokel
typo
  • Like 1
Link to comment
Share on other sites

Update: both players are playable, but player 2 is very broken and does not colide. Also, the opponent car still in a fixed position of the screen. But this is the first revision that gives the feeling of what the final product will be. I am eager to see if you still think the 2PE is playable.

(Tech part)

Extracting the code to SBR was a interesting way to see hard dependencies boundaries.

Example, the break routine is interlaced with accelerate, since when you break you don't accelerate, and if you do both, you break with half speed, and don't accelerate, so all the jump points should be part of the same SBR, helping to make sense of the code.

Most of Atari registers are offset by 1 for each player, making possible to effectively using X to offset things and call the same SBR for both players.

STY HMP0,X
LDA INPT4,X


But some are not, like SWCHA, but you can make it work like it is. This might be obvious for experienced 6502 devs, but was a nice discovery for me:
First version of the code, passing the masks to the SBR:

CallProcessSpeed
    LDX #0
    LDA SWCHA
    LDA #%00100000
    STA Tmp1 ; Down mask
    LSR ; #%00010000 Shift uses only one byte
    STA Tmp2 ; up mask
    JSR ProcessSpeed
    INX ; Player 1
    LDA #%00000010
    STA Tmp1 ; Down mask
    LSR ; #%00000001 Shift uses only one byte
    STA Tmp2 ; up mask
    JSR ProcessSpeed

And used in the SBR as:
    LDA Tmp2    ;UP in controller
    BIT SWCHA 
....

 

But you can make even make the masks offset friendly save bytes and make the code more readable by doing this:

PlayerToUpMask
    .byte #%00010000;
    .byte #%00000001;

PlayerToDownMask
    .byte #%00100000;
    .byte #%00000010;

CallProcessSpeed

    LDX #0
    JSR ProcessSpeed

    INX ; Player 1
    JSR ProcessSpeed

And use like this:
    LDA PlayerToUpMask,X    ;UP in controller
    BIT SWCHA 

 

Have a nice day.

  • Like 2
Link to comment
Share on other sites

The opponent car is displayed in the correct line.

 

(Tech part)

Hellway tries to maximise the vertical area as much as it can, by reducing vblank and overscan times. While design the first game I tried to keep the top of hud digits to the tail of the car (see attached pictures), inside the area recommended by the Stella developer manual, so even in old tvs the game would be fully playable, but the vertical area would be better in most televisions, giving some space behind the car.

When I started calculating the correct opponent line, I broke the line count. Before enabling it, I had to find a better solution for my naive approach of doing most of my 10 WSYNC and HMOVE during the vblank. 

I realised I could have it almost for free, if done in an already WSYNC part of the games (and not waste 76 cycles worse case), the solution was to do it while drawing the hud that is playfield based only, and already had the WSYNC and enough free cycles. The downside are the black bars you see, but they are not so bad in the default dark mode.

This solution allows me to position everything without spending vblank time, keep the physics and control input at 60 fps and keep the increased vertical size of the game.

 

hellway2pe.asm_4.png

  • Like 3
Link to comment
Share on other sites

Redesigned HUD to work with 2 players.

I am using vertical bars that are filled 3 line on the horizontal and when a line is completed another line starts.

It works as a separator as well, and in much more intuitive than an hexadecimal, there is a clear sense of progress.

In the middle is speed, in the corner, how much progress you have in the level, when the bar is full, you are close to a checkpoint. I decided to mirror the player 2 hud, is more pleasing aesthetically and easy to see how close you are of the opponent.

 

The idea is to get ride of Hexadecimal, the timer (in the conners). Would be ok to have max of 99 seconds. The checkpoint number (close to level bar) I have only one digit, my idea is to keep going all the way in the alphabet. (0,1,2....9,A,B...Z). It is ok to say you are in checkpoint K and opponent in J.

Ironically, my font is 3x5, and the bar has 16 possible values, so, it is like a hex digit, but makes much more sense.

 

hellway2pe.asm_7.png

hellway2pe.asm_5.png

  • Like 1
Link to comment
Share on other sites

Game is playable! Checkpoints, glide and game over are working for both players. Also disabled score screen, so the game does not break until I change it properly.

There are still several things to be done, but this version is the first that you can really compete (players do not collide yet). For me it is being harder to fine tune the game because of the 2 players aspect of it.

Would you (community) consider test the game and share feedback / ideas ? 

Anything that comes from this interaction will be properly credit, any help will be much appreciated.

hellway2pe.asm_9.png

  • Like 3
Link to comment
Share on other sites

Collision Between players is working.

There are 5 possible states a car can be.

Default (yellow or blue for P2)

After collision (Smashed)
Checkpoint (green)
Gliding (red)
Game over (white)

I decided after some thoughts to make the rules as simple as possible:

The cares only collide if both are in the default state, in case of a collision the car that is behind suffers a hit.

This might still change, the reason behind the rules are:

 - The player in front can defend its position, the player behind must properly overtake.

 - After collision, one (or both players) do not collide with the traffic, and should not collide between them, giving time to recover.

 - At checkpoint, would be relatively easy to run over the other car while invincible, since your enemy might have to stop for traffic, he will be a sitting duck.

 - While gliding, it would be too unfair to finish the opponent with one move

 

 - At game over, an already dead player should not be able to kill a possible gliding player with one move.

 


I am open to suggestions, I am not 100% yet this is the best way to implement this.

 

  • Like 2
Link to comment
Share on other sites

New Update:

Fix the bug of passing several times by the opponent introduced in the last version.

Removed hexadecimal, now the timers are decimal and checkpoint count just continue the alphabet.

Both players have sound, each player uses its own channel, and sound effects have priority over the engine sound.

Dev log, stardate 1647891096:

I am using an 1 byte result version of this routine (http://www.6502.org/source/integers/hex2dec-more.htm) to do the BCD conversion on the fly, but it still should be over 150 cycles just to get one BCD digit (I just need one per frame). Other options includes:

- Keeping 2 extra bytes and do everything you do to the main counter to a bcd counter, this includes replicating lookup tables to have the checkpoint times also in decimal.

- 100 bytes BIN to BCD lookup table.

- Ignore the fact that everybody hates hexadecimal and just keep using it :)

I am approaching CPU cycles (If I don't increase blank times) and RAM limits, the final solution will depend where I die first.
 

Edited by Octavio Pinho Bokel
Forgot routine link, finish decimal
  • Like 1
Link to comment
Share on other sites

New Update:

Random difficulty now works.

If the player is in front, he gets a random difficulty, the player behind always get the same difficulty of the player in front, making the screens consistent!

If they are in the same line (very very unlikely), I just give both the default difficulty for the level.

Dev Log:

I was shocked to see that I reached the 4KB limit today. I removed all the remaining code for the score screen, but there is not much left I can remove, let's see how things go.

90% of the code I reuse for both players, but there is still the overhead of calling the subroutines instead of inline code and preparing the parameters for each call. 4KB was gone fast... It begs the question, should I bank switch?

  • Like 1
Link to comment
Share on other sites

4 minutes ago, Octavio Pinho Bokel said:

90% of the code I reuse for both players, but there is still the overhead of calling the subroutines instead of inline code and preparing the parameters for each call. 4KB was gone fast... It begs the question, should I bank switch?

I guess it depends on your reason for avoiding doing so in the first place. Size limits can be a fun challenge, depending on the project. If you have ideas on features you could add if you had the space, then you might want to go with the bankswitching option.

 

Oh, and it depends on whether or not you want the game to compete in the <=4K category next year. :P

  • Like 2
Link to comment
Share on other sites

New update:

Updated into text.

Introduced the ready text. Both players have to be pressing fire at the same time for the game to start, solving the problem of one player starting before the other. The player pressing fire will show ready on its half of the screen.

This was much more simple than doing a countdown, since all the state keeping I have to do is done by INPT4 and INPT5, and is as effective.

@Karl G, Probably I can still make the 4kb. What I am afraid is introducing bank switching, and having a 4,5 kb games. I know myself, if do introduce, I will have to fill the 8KB... I don't think this game will win anything in any category. The original already required some time investment to be enjoyable, this one also requires 2 people, making it harder for people to play and vote...

hellway2pe.asm_11.png

hellway2pe.asm_12.png

hellway2pe.asm_14.png

  • Like 2
Link to comment
Share on other sites

Version Update:


Fix player 2 checkpoint text.
 

I got ride of the score screen, makes not much sense for 2 players and will be impossible to fit in 4KB. I solved the end screen by:

- No more game over text, so the scores are kept.
- Time and speed are replace by a clear indication of the player position (1 or 2)

This was by far the less resource demanding solution, resources are getting scarce.

Next, I have to solve how to differentiate the players that are using the same car and are in the same non default status (checkpoint, game over, glide...) they now look the same and can be confusing...

hellway2pe.asm_15.png

  • Like 2
Link to comment
Share on other sites

Version Update:


- Aligned each player screen perfectly with each player score.
 
- Kept only dark mode. The BW switch still can be used on the QR code for better camera reading. It is expected QR codes to be dark in a light background, I just reversed the default because it is still readable by most devices, and hurt the eyes the screen almost all white, going to a black background, and vice versa. Due to the flickering, all non dark backgrounds looked bad. This made me save some bytes.

- Removed the completely obscure alternate flickering mode on the score, since the game is all flickering now (Saved more bytes)

- Each player now have distinct colors for each status, so they will not look the same anymore if using the same car. For this one I also considered giving each player distinct car models, but due to space and the fact that collisions are done by hardware (different models for the same car would affect the gameplay if not exactly the same outer pixes) I gave up on the idea.
 
 

hellway2pe.asm_17.png

hellway2pe.asm_18.png

hellway2pe.asm_19.png

  • Like 6
Link to comment
Share on other sites

  • 4 weeks later...

EXCLUSIVE FINAL VERSION of

  HELLWAY 2 PLAYERS EDITION  

FRIDAY APRIL 22 on ZEROPAGE HOMEBREW

WATCH on TWITCH LIVE @ 6PM PT | 9PM ET | 1AM GMT+1Day

https://www.twitch.tv/zeropagehomebrew/

 

870118479_20220414-Hellway2PlayersEdition.thumb.jpg.9fa7a9c111e4b0ffdc52a76ea1bfec2e.jpg

 

 

We will be playing the EXCLUSIVE FINAL VERSION of @Octavio Pinho Bokel's Atari 2600 homebrew Hellway 2 Players Edition this Friday Apr 22 on ZeroPage Homebrew! Tune in to watch Tanya and I go head to head racing through the busy streets in this exciting racing game!

 

- James

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Hello you all!

 

Thanks for being heree during the journey!

 

I will restore the binary links after @ZeroPage Homebrew plays it (they are broken for a while). It had several updates from the last time I reported, and the reason I was silent on the forum, to make it exclusive.

 

For me is a very special occasion. I will be in the chat during the stream, and will be answering any questions you might have.

 

See you there!

Edited by Octavio Pinho Bokel
  • Thanks 1
Link to comment
Share on other sites

ZeroPage Homebrew is playing the Exclusive Final Binary of Hellway: 2 Players Edition on tomorrow's stream LIVE on Twitch, hope you can join us!


Games:

(WATCH AT 1080P60 FOR BEST QUALITY)

 

  • Thanks 2
Link to comment
Share on other sites

Hello,

I going to post all private @ZeroPage Homebrew updates, so you know what you missed, and the current status of the game!

New update:

 - I made Player 2 Green and Player 1 during checkpoint. Since player 1 is yellow, it was a little confusing the P2 turning into a color that was very close the default P1 color.

 - During checkpoint and start, now there is a countdown progress bar that tells exactly when the invisibility will end. This will be even more useful in the next update.

 
hellway2pe.asm_20.png

 

Edited by Octavio Pinho Bokel
  • Like 1
Link to comment
Share on other sites

Fixes for the above message:
* I made Player 2 Green and Player 1 Orange during checkpoint
* invincibility, not 
invisibility

New update:

 - I just introduced something to keep the game play really competitive, rubberbanding.
The player that is behind will have the checkpoint time countdown decrementing at half rate.
This can double the checkpoint time. If you pass the opponent, now the opponent time starts decrementing at half speed and yours at normal rate. That is way I say it decrements at half rate, and not that it gains double time. The countdown bar is now a much more useful feature.

- Rubberbanding can be disabled by turning the black and white switch to black. This was simpler then doubling game modes and gave another use to the BW switch. If rubberbanding is turned off, a pipe appear on the only space left in the intro screen, in the middle.

- When the HUD shows my name and year, the second time it shows my name and build number. Since there is no more score screen, this is a way to know for sure you are playing the correct build.

 

hellway2pe.asm_22.png
 

hellway2pe.asm_23.png

 

hellway2pe.asm_24.png

Edited by Octavio Pinho Bokel
  • Like 1
Link to comment
Share on other sites

Update:
 

 - Fixed line count during reset.
 

 - Added 2 arrows that appears when the opponent is out of screen, but still in a close range. It is like you extend you screen a little more regarding the other player position, giving more time to position for an overtake. In case of the winning player, is like a rear view mirror, allowing to block the other player. I putted the arrow in front of the player just because in some televisions it might not be visible behind the car (overscan).

 

hellway2pe.asm_26.png

  • Like 1
Link to comment
Share on other sites

Update:

I restored the non dark mode functionality, moving the rubber band feature to the reset switch, with each reset that has no change on config toggling it (Similar to how you changed cars in the previous game). Dark mode still default on this game.

The reason is that I made a research about flickering on AA, and is a very controversial topic. For me the game is totally ok with a stable 30hz, and even close to normal with phosphor mode on in Stella. But when I tried in other monitor, the effect was much more noticeable.

The individual perception is also a key factor. It is impossible to me to know the effect on each person, but what I can do is to offer a grey background that looks bad, but reduces contrast and flickering perception in some cases.

This game cannot run without flicker, not without extra hardware. With an arm CPU and extra RAM I could create a framebuffer like structure and just draw the elements on the screen in a non mirrored manner. But this is a huge amount of work, and defeats my self imposed challenge.

hellway2pe.asm_27.png

  • Like 1
Link to comment
Share on other sites

Some considerations about the @ZeroPage Homebrew stream last night:

First, congratulations, I think you mastered the game, and understood the vision behind it. You are both playing it much better than last time!

About the first play:

Tanya, your car was indeed worse and was an unfortunate choice. Let me explain He is like the default car with less acceleration, but is very, very good at gliding. This means that he has a clear disadvantage on regular time, but when time is over, if you don't make any mistakes, you can almost glide forever and reach far. It is a risk reward strategy and is the one that varies more the score each time you play.

James, the car you choose is the best beginners, it accelerates fast (meaning less punishments on crashes), and a reduced top speed might actually work on your favor, reducing the number of crashes.
Regarding that, your score was very very high, and you played almost flawless. I tuned the game a little after watching you play (increasing the traffic levels a little closer to the original). If you play the single player plus cart version this would be a score close to 4832, beating my high score of 4066 for this car. Hellway is a game that gets better when you get the flow of it.
https://highscore.firmaplus.de/?page_sort=1&sort_order=0&game_id=35&game_variant=BB+Mode+0+Car+1

 

 

About the second play:

Changing the the traffic level is not the same as changing the difficulty. More traffic also gives you more time per checkpoint, keeping things balanced. It is all about adapting you gameplay progressively from more aggressive to one that is about being patient and waiting the openings. If the game cycles the switches, change the starting level.

There are two settings that can make the game harder, the high speed diference on the lanes and using random traffic intensity mode, on a fixed level that gives you a small amount of time. The time is always fixed regarding the level, so it will average to a harder overall experience. Random can also go over the fixed limits.

Please note that the QR code landing page is interactive, you can just select the options you want, and it will tell you what mode to select.

The gameplay while short, it was super competitive and fun, it was exactly what I tuned the gameplay. The first game is all about high scores, while the seconds, is all about winning the other player. I had much fun watching this one.

James, your car (Dragster) needs some time to get the hang of it. The fact it turns slow, means you to have to break more, because it takes more time to change lanes. But you recover this speed also faster. Fast acceleration and top speed are great for low traffic levels and for using on checkpoints (best car for checkpoints).

Tanya, you played great. If you had pushed you car to the right lane, you probably would pass that last checkpoint.

Sorry for the long text, I just wanted to give my overview of the stream, and some insight if for some reason you decide to play my game again, and also for the people watching! Please let me know if it helped.

Thanks for all your work!

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

Loading...
  • Recently Browsing   0 members

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