![]() |
![]() |
#1 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
Entry: ModSurfer
Title:
ModSurfer Genre: Rhythm Original concept: No. Heavily inspired by the PC game AudioSurf ( [ Show youtube player ]), which builds a track with synchronized bends/hills and items to collect from an audio file. ModSurfer will derive the track from a MOD file. Expected game size: Each game will last up to the length of the selected MOD file (or until it loops). MOD files will be provided by the player from their collection. Team members (Real or forum names): arcanist Targeted spec: A500 with 1MB. Larger MOD files will need more chip RAM. Tools to be used: GCC and VASM. ptplayer to handle audio playback. Description of game: From the title screen the player selects a MOD file from their collection, through a simple file browser with a MOD header decoder. The track and sample data is pre-processed to build a 3-lane pseudo-3D (Lotus-like) track with synchronized curves and hills. Items will appear on the track in time with the beats to collect. Hazards may be added later but the goal is to keep the experience as relaxed as possible. Scoring is based on the total percentage of items collected. Difficulty will vary with the speed of the MOD file and its samples. |
![]() |
![]() |
#2 |
Global Moderator
Join Date: May 2001
Location: Derby, UK
Age: 46
Posts: 2,304
|
Please remember this thread is for arcanist to post his updates only.
The discussion thread for this game is here: http://eab.abime.net/showthread.php?t=93667 Any other posts will be moved into that thread and all updates copied in there. |
![]() |
![]() |
#3 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
I've hooked up audio playback through ptplayer. This runs by itself through a CIA interrupt timed to the song's current BPM. Seems to work fine, Frank did a great job.
To build the "track" the player will move along I've implemented a MOD parser. It walks through the entire song to figure out what will appear at each step, and how much time will pass between steps. This will eventually try to identify beats from the ADSR envelope of each sample but for now just makes a note when a sample plays. I wanted to test synchronization between the audio and visuals so I put together the demo below. My initial attempt relied on precalculated speed to move visuals independently of the audio, but this incurred some problematic drift over time. I reworked it to synchronize with ptplayer as it steps through the MOD, leaving calculated speed to interpolate movement between steps. The demo below doesn't interpolate movement, though, as the scrolling method is not relevant to the 3D track that will eventually be used. I'm now working on the 3D component. This uses the copper to render track edges and stripes. In each scanline sprites of appropriate width are manually constructed (no DMA, written straight to SPRxDATx) and the sprite channel is reused throughout the scanline. It's currently 2D while I work on the projection math. [ Show youtube player ] |
![]() |
![]() |
#4 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
This is a prototype of the "track" on which the player moves. I've added keyboard (A/D left/right, release to center) and mouse control. This method trivially supports track bends left and right, by shifting scanlines, and can also show hills.
On each scanline the copper programs a 3x1 pixel sprite to appear at the left and right stripes, loading data manually to avoid DMA. The positions are calculated using an integer Bresenham algorithm with perspective-correct lines. I did some limited optimization to get it running on an A500 at 50Hz but haven't rewritten the code in assembly yet. I ran into an issue with ptplayer's timer interrupt on the emulated A500 causing an odd delay when it coincides with the vblank (I have VERTB interrupt disabled). For now I recorded on an emulated A1200. The next step is to decide between this approach and Lotus's method, which blits from a precalculated image on each scanline. I'd guess the copper method is faster (six CPU word writes per scanline) for a bare track. However, next I want to introduce the "blocks" the player will try to hit. There may be quite a few on screen; certainly more than the sprite channels I have. Reusing channels down the screen is one option but difficult to pull off when the blocks overlap. Displaying them as bobs would be asking a lot out from the blitter. The upside is the blocks could be displayed as vertical objects. I'm considering a different idea: making the blocks flat on the track. It's less visually impactful than hitting a vertical object but I could spruce it up with sprites when the player hits one. The advantage of this is I could merge it with the Lotus approach; on each scanline there would be 1 of 8 configurations (0-3 blocks across the lanes) and the program would pick a line from eight pre-calculated images to blit. The blocks would also have perspective depth with this method. [ Show youtube player ] |
![]() |
![]() |
#5 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
Here's a bonus failed attempt!
I had an idea to implement perspective by drawing the track stripes and blocks into an image, with the camera centered, offline. I then programmed the copper to set the bitplane fetch/scroll on each scanline with a shift corresponding to camera movement. The shift is calculated as a line extending from the near plane to the far plane. Objects could then be shown/hidden per scanline just by writing color/black to the four color registers. Genius, I thought! It turns out that drawing lines in the centered camera image "bakes in" sub-pixel errors. When it's shifted by another Bresenham-calculated line the combined error becomes super-pixel and the lines, while following the correct paths, go all wibbly. I went to YouTube to see how Lotus 2 solved this and apparently they didn't! If you watch the road markings there's a lot of artifacting. They just move everything so fast I never really noticed. ![]() Guess this approach isn't going to work out. Back to sprites! [ Show youtube player ] |
![]() |
![]() |
#6 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
This week I added some more graphical elements and fixed/optimized for the target A500 platform.
I've settled on the 3D display implementation. The tracks and blocks are pre-rendered to a bitmap with each lane in a different color (1 = lane markings, 2/3/4 = blocks across lanes). The copperlist looks like this, repeated for each scanline: Code:
0001ea04: 7201 fffe ; Wait for vpos >= 0x72 and hpos >= 0x00 ; VP 72, VE 7f; HP 00, HE fe; BFD 1 0001ea08: 0108 0004 ; BPL1MOD := 0x0004 0001ea0c: 010a 0004 ; BPL2MOD := 0x0004 0001ea10: 0102 0066 ; BPLCON1 := 0x0066 0001ea14: 0182 0000 ; COLOR01 := 0x0000 0001ea18: 0184 0804 ; COLOR02 := 0x0804 0001ea1c: 0186 0000 ; COLOR03 := 0x0000 0001ea20: 0188 0000 ; COLOR04 := 0x0000 The COLOR register writes show/hide the lane markings and blocks in each lane. During each frame the CPU updates these entries to reflect the state of the track as it moves towards the camera. This is where the bulk of CPU time is spent; currently 2/3rds of a frame but I think I can optimize it further. The copperlist is double-buffered so that the CPU can work outside of the vertical blank. This approach makes it trivial to curve the track left/right (shifting the scanlines accordingly) and even add hills/dips like Lotus, by compressing/expanding Z increments down the image. I plan to add sub-pixel anti-aliased lines to the bitmap to soften the visual artifacts but right now I want to implement all the basic game elements. Instrument selection for blocks on the track is the biggest piece of work remaining. In the video below I've manually selected three lead instruments to give a rough idea of how the game will play. I expect I'll add non-collectible blocks to make pathing a little harder. [ Show youtube player ] |
![]() |
![]() |
#7 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
I've started work on instrument selection. The goal is to find good samples in each pattern to correlate with collectibles on the track. This needs to work with any mod the player might provide.
The first piece I've chosen is pitch detection. We want to avoid repetitive drum/bass instruments and pick out the leads. Lead instruments will generally play at a higher pitch so this will form part of the "score" assigned to each instrument. The dominant frequency in each sample is retrieved from its frequency spectrum, computed with a FFT on the sample data. This is combined with the playback pitches to calculate a per-pattern mean pitch. To show how powerful this is by itself, the video below shows the game choosing instruments just by their pitch. This contrasts with the previous video where I picked a few instruments by hand. (The code isn't optimized yet so please gloss over the startup time. ![]() I plan to add further weighted components to the instrument scores. Per-pattern playback counts and mean volume are low-hanging fruit. I have some other ideas but to explore them fully I'm going to implement a debug overlay in the game to show the scores in real-time as the song plays. [ Show youtube player ] |
![]() |
![]() |
#8 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
|
![]() |
![]() |
#9 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
This update introduces a completed file browser. There was a lot of uninteresting plumbing code here so I didn't make an interim post.
The video below shows how the browser works. The panel on the left gives details about the selected mod. It actually displays the instrument names but this was a common location for artists to write a piece of text about their work. I introduced a new gameplay feature. If the player misses a block then the corresponding instrument doesn't play. The first part of the video shows this in action. It makes the gameplay a bit more interactive and I really like it. To give the player time to activate blocks from the side (rather than just the front) the sound can't begin playing until the block has passed. This introduces a small delay that wasn't present in earlier builds. I'm not super happy about this but I think the game might be too difficult on faster tracks if the player can only activate blocks from the front. For the nosy devs among you I've uploaded the current code to GitHub. Some of it is pending cleanups but it's in reasonable shape. The source code cross-compiles with amiga-gcc. I develop from a Linux system but it would also build on Mac OS X and Windows (with a native C compiler for the meta-compiling steps). https://github.com/amigageek/modsurfer I've picked one of my favorite tracks for the second part of the video. It's quite fast and feels great to play. (Captured on an emulated A1200 pending an optimization to start-up time for A500.) [ Show youtube player ] |
![]() |
![]() |
#10 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
Track curves did not work out well! I put together a quick prototype and... it just doesn't look good in a game without physics.
![]() The technique is an extension of the method used to move the camera. Each scanline is shifted horizontally by a different amount. By increasing the shift from the bottom to the top a bend is formed. I think I'm going to experiment with hills/dips instead. I've got about 1/3rd frame time to spare on a 68000 so it'd be a shame to waste the cycles. [ Show youtube player ] (Excuse the audio glitches. Something's broken between WinUAE and OBS.) |
![]() |
![]() |
#11 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
I've run through about 100 mods to find bugs and tune the algorithm. I picked 10 of my favorites for a demo disk so far.
Today I've been tuning the difficulty for fast tracks. I think the engine is a bit too enthusiastic about placing blocks in alternating left/right lanes, which requires fast mouse movement. It's more fun to slide left to right and back so I'll probably tweak the track generator a bit. I spent an hour playing fast tracks today and they're super fun. I've recorded a couple of them back to back in the video below. Getting that "one more go" vibe with your own game is a special kind of feeling. ![]() [ Show youtube player ] |
![]() |
![]() |
#12 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
During the festive break I spent some time fixing bugs and polishing up the graphics. I ran out of frame time along the way. A quick rewrite of the most time intensive code (copperlist update) from C to assembly brought the result back to around 70% frame time. Now I have to figure out how to spend it.
![]() Blocks on the track are now colored according to the note being played. This looks better in some mods than others. It works especially well with long pitch slides. I didn't like the ship sprite so I knocked up a classic boing ball in Deluxe Paint IV and added everyone's favorite color cycling pattern for that rolling goodness. There's now a basic "sky" gradient to fill in the blackness. I'm also playing with a gradient in the track stripes and edges. The game currently pulses the brightness at the speed of the track. I was thinking of something more interesting to do with it. Perhaps a hue shift as the track completion % approaches 100, or tied to the number of blocks in the area. Excuse any capture artifacts in the video. I can't figure out how to get OBS to capture 50Hz reliably. I also had to disable WinUAE's lagless vsync mode to record without tearing. The game works fantastically in lagless mode, you can really feel the lower input lag. Props to Toni! [ Show youtube player ] |
![]() |
![]() |
#13 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
ModSurfer is now feature complete! I plan to spend February making small tweaks and testing. The game will release into public domain on the competition deadline.
This update introduces a left/right rolling ball animation. It isn't quite how I hoped to implement it. I learned that the color cycling boing ball always rolls in the direction of the checker pattern. If the pattern is rotated then it's not possible to get a forwards-rolling effect with color cycling (without a lot more colors). To overcome this the ball rolls back upright when movement stops. I think it still looks quite good. Might need a little tweaking to smooth out motion when the ball is rolling slowly. Instead of making one sprite for each angle in Deluxe Paint I coded a small ray tracer into the build system. There's now a primitive VU meter into the borders of the track. This was a suggestion from the discussion thread but made a bit simpler. I thought about doing one meter in each lane but without more colors I couldn't fill the width of the lane; only the width of the block. It looked better to me in the borders. In this video I try three increasingly difficult tracks (and rage quit at the end ![]() [ Show youtube player ] |
![]() |
![]() |
#14 |
Registered User
![]() Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 418
|
Release thread
Direct link Thank you to everyone who contributed on the development thread. I didn't manage to incorporate all the feedback but it helped me shape the game and was appreciated. Six months is a tough timeframe. ![]() Some clarification for judges:
![]() |
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
No entry for Argonaut's A.T.A.C.? | Aegis | project.aGTW | 10 | 02 February 2016 13:43 |
New entry - HUSARIA | mailman | HOL contributions | 3 | 08 November 2008 10:19 |
False entry ? | Another World | HOL data problems | 1 | 21 August 2008 22:12 |
|
|