From memory, you'll want to not use Unity's built-in physics. I implemented the physics in Unreal Engine 4, and the biggest issue I had for a while is that you couldn't change the direction of gravity for a single object - something that, iirc, Unity doesn't let you do at run-time on a per-object basis either. I could be completely wrong, but it's something worth looking into imo.
I've actually been avoiding using Unity physics where possible aside from raycasting purely to replace the sensors, not even a rigidbody. Just tile colliders and raycasting. It is a bit surprising that there isn't a proper 2D implementation of Sonic physics for Unity and/or UE4 out there. Dash Engine for UE4 supposedly has one, but I cannot for the life of me get Dash Engine's arcane build process to work properly, so I can't test it.
Sweet merciful jesus, yes... I wish you were around to do this back when I first started working on my own engine in 2010. I'm combing through it now, and it is a massive improvement. Maybe now some of these Sonic Worlds engines can actually get their goddamn physics right instead of feeling janky and floaty.
This is why I'm having the engine being completely rewritten from scratch using this guide as a basis. :O
Awesome guide but Ive still got a ton of questions (mostly how different badniks work in the games but also some more slope stuff). How would I go about getting the missing info myself? I noticed you mentioned recording, what software do you recommend?
I mostly look heavily into the Disassembles (ASM code) to understand and reconstruct systems, learn the logic and get any precise values. Steep learning curve though. You can sometimes record the game and count frames or motion for things like some animation speeds (but not variable ones like Sonic's walk/run) or movement speeds of things that don't vary (like not gravity, but you can measure projectiles that travel straight or motobug's horizontal movement etc). Typically though, reading the ASM disassembly code is the way to go. However, I & Mercury have also done some of the work for you with the Sonic 1 Overlay https://info.sonicretro.org/SPG:Overlay_Scripts It can show you all of Sonic's variables, and also all object's solidity, hitboxes, and terrain sensors. Should help you with small nuggets of info with how certain things work in S1. Updates to it are coming so be sure to check back here, I will post about it. Also working on the same for 2 and 3k. Shows you all the solid slope tiles too! Though all info you need about how slopes work should be on the guide. ------------------------------------ Some recent Physics guide updates: - Game Enemies now have their own page! (https://info.sonicretro.org/SPG:Game_Enemies) The goal will be to fill this page with explanations of both Badniks and Bosses of each game. The existing Game Objects page will expand and focus on general gimmicks. - Some information has been lifted from the "Solid Tiles" page to it's own "Slope Collision" page (https://info.sonicretro.org/SPG:Slope_Collision), allowing for easier navigation and more focused explanations on each. - Research is being done for the mechanics, collision and physics of the Sonic 1 Special Stage: https://twitter.com/LapperDev/status/1495565387093745665 Essentially been doing some code experimenting recreating the Special Stage physics while researching the code. Did the same with Solid objects a while back. The video is a heavy wip of course - it generally functions, was just a couple hours investigation. Once all the features can be replicated and understood it will end up written up on the guide.
Update of the recreation of special stage physics research (First half is the recreation and original overlaid ontop eachother, and second half is a comparison). Thanks to Mercury for helping & figuring out some of the more complex details. Very close to being fully explainable.
A quick question. In the camera page, it says this: Looking at the original assembly code, the scroll cap is 6 px/frame if the ground speed is less than 8, otherwise, it's 16 px/frame. Where'd the "if the Player's Y speed is less than or equal to 6" part come from? For example, in the Sonic 2 disassembly: Code (Text): mvabs.w inertia(a0),d1 ; get player ground velocity, force it to be positive cmpi.w #$800,d1 ; is the player travelling very fast? bhs.s .doScroll_fast ; if he is, branch ;.doScroll_medium: move.w #6<<8,d1 ; If player is going too fast, cap camera movement to 6 pixels per frame cmpi.w #6,d0 ; is player going down too fast? bgt.s .scrollDown_max ; if so, move camera at capped speed cmpi.w #-6,d0 ; is player going up too fast? blt.s .scrollUp_max ; if so, move camera at capped speed bra.s .scrollUpOrDown ; otherwise, move camera at player's speed .... ; =========================================================================== ; loc_D7FC: .doScroll_fast: ; related code appears in ScrollBG ; S3K uses 24 instead of 16 move.w #16<<8,d1 ; If player is going too fast, cap camera movement to $10 pixels per frame cmpi.w #16,d0 ; is player going down too fast? bgt.s .scrollDown_max ; if so, move camera at capped speed cmpi.w #-16,d0 ; is player going up too fast? blt.s .scrollUp_max ; if so, move camera at capped speed bra.s .scrollUpOrDown ; otherwise, move camera at player's speed The fast vertical scroll cap is 24 px/frame, in S3K, too (the level renderer in S3K can draw up to 2 rows/columns of blocks at once). I'd make a wiki edit, but I also didn't want to tread over your work at the same time.
Ah, so looking back through the edits those used to both mention "Y Speed" and "6", seems a correction was made to the info in one set of brackets and neglected to correct the other. If you want to make a correction based on knowledge of the assembly code, you can definitely go for it of course.
A'ight. I also went ahead and redid a few explanations to be more accurate to how the Assembly code works, and also how it functions between the different games. Particularly wanted to explain the "focal point" (or "bias") variable(s).
Recent additions/changes made: Object behaviour/collision breakdowns: Diagonal Springs SLZ Seesaws CNZ Flippers SLZ Fans OOZ Fans Sloped objects added to the guide now also have their actual height array data from the game transcribed. Improvements to Sloped Object height array explanation.
I found a slight inaccuracy/piece of incomplete info in the section on jumping: Through testing with the overlay mod (thank you for developing that, too ), I found that the exact same thing occurs in Sonic 1 as well. Correspondingly, the issue of 1 frame where Sonic is 5 pixels too high after landing happens there as well.
Also happens in Sonic 3K as well. What's going on is that it checks if Sonic is rolling after resetting to the default hitbox size, and if he's rolling it goes to another piece of code that sets a flag, but doesn't shrink Sonic's hitbox down. Interestingly, it doesn't happen in Sonic CD. Sonic CD doesn't reset the hitbox size to default before checking if Sonic was rolling before jumping like the mainline games do.
I assume that has to do with the fact that Sonic CD is the only one among the main Genesis games to not prevent you from changing direction after jumping from a roll?
Actually, it still sets the roll flag and skips over the code that sets the shrunken hitbox size, it just doesn't check it in the horizontal movement function when in the air. The actual change in this case is that they removed the code that resets the hitbox size to the default size before shrinking it, so if you were rolling before, it should remain shrunken.
Oh right, thanks for pointing this out. I knew this already so I'm not sure why it's written that way. Probably because landing from a roll jump in S1 feels fine when playing, but you can notice it easily in S2.
I asked a question a few weeks ago about how the tile layering/paths system works, and Devon offered some extremely in-depth responses (first, second, third) with great demonstrative images and gifs and such. I noticed that the physics guide doesn't contain this information, which is essential for creating an engine that can handle more complex level layouts. Could these responses be integrated into the physics guide?
Recent additions/changes made: Special stages page added Rotating Maze explanation added (images, animations, and more detail will come soon) Absolutely! Been meaning to go more into loops and things like that, including layers. With the Sonic 2 Collision Overlay currently in development, it will give even more opportunity to show realtime visual examples of that kind of layer swapping too, so this is all planned to be added alongside that.
I just noticed another minor thing with the wording of the "rolling" state's description: Does this mean Sonic cannot "roll up" as in "roll into a ball from an upright position," or does "roll up" mean "sonic cannot roll up a slope" unless his absolute X Speed is greater than or equal to 0.5? It's a little thing, but the 2 different interpretations are quite different. (also please let me know if these small critiques are unwelcome/should go elsewhere).
0.5 is the minimum speed you need to be able to roll into a ball at all. "X speed" should also be "ground speed". Code (Text): Sonic_Roll: tst.b (f_jumponly).w bne.s .noroll move.w obInertia(a0),d0 ; (Ground speed) bpl.s .ispositive neg.w d0 .ispositive: cmpi.w #$80,d0 ; is Sonic moving at $80 (0.5) speed or faster? bcs.s .noroll ; if not, branch move.b (v_jpadhold2).w,d0 andi.b #btnL+btnR,d0 ; is left/right being pressed? bne.s .noroll ; if yes, branch btst #bitDn,(v_jpadhold2).w ; is down being pressed? bne.s Sonic_ChkRoll ; if yes, branch .noroll: rts ; =========================================================================== Sonic_ChkRoll: btst #2,obStatus(a0) ; is Sonic already rolling? beq.s .roll ; if not, branch rts ; =========================================================================== .roll: bset #2,obStatus(a0) move.b #$E,obHeight(a0) move.b #7,obWidth(a0) move.b #id_Roll,obAnim(a0) ; use "rolling" animation addq.w #5,obY(a0) move.w #sfx_Roll,d0 jsr (PlaySound_Special).l ; play rolling sound tst.w obInertia(a0) ; (Is Sonic stopped in a spin tunnel (spin tunnels skip the check above)?) bne.s .ismoving ; (If not, branch) move.w #$200,obInertia(a0) ; (If so, boost Sonic to the right) .ismoving: rts