I'm working on a Tetris implementation that I hope will blow away every other implementation out there. Here's an early, simple two player theme screenshot: Thanks to "tetrablocks" for the block images, I haven't gotten around to making some yet. The game is infinitely configurable and will implement battles over the internet, with multiple team play configurations, FFA and whatever else I can think of. I'm posting for two reasons: 1) Let the community know about it 2) Get feedback on what game play issues are a must, and what people are looking for. I could go on and on about what I've got designed into the back end, but that would just be a waste of time. If you guys are interested I can answer any questions, and I'll certainly post up newer versions as they come along. Today I'm posting up a very early version that doesn't have any bells and whistles implemented in the front end. This is just to get some feedback on the game play and see what you guys think is good and what is lacking. Things like High scores, an opening screen, configuration, and network play are all already under development -- most of it is already implemented, just not designed into the GUI yet. Anyway, let me know what you think. I put together a quick single-player theme for this, so it's a little different than the screen shot. This requires Java. It's rendering in OpenGL via slick and the rest of the GUI is done in swing. The key config is currently: Without "Num Lock" on: Soft Left: Numpad 1 Soft Right: Numpad 3 Soft Drop: Numpad 2 Hard Left: Numpad 4 Hard Right: Numpad 6 Hard Drop: Numpad 5 Rotate Clockwise: c Rotate Counter clockwise: z Flip(rotate twice): x Pause: p Please let me know what you like and don't like. I hope for this to eventually be very user-base oriented, so I care a great deal what people like and don't. P.S I had never seen the "hold block" feature before, but I like it and I'll implement it as an option soon. Download Newest Version: Game v0.6.5
Well ignoring the cockiness, good luck beating out lockjaw. If i were you i would go for the multiplayer angle because currently we lack a good multiplayer tetris.
I'm sorry, cockiness wasn't my goal. I'm excited about the project is all. I started working on it a while back when I couldn't find a good tetris clone out there. Now that I've gotten this far along and discovered LockJaw, I can only hope to do what it does and then some. Multi-player has been my goal from the beginning, so I'm glad to hear I'll be able to at least fill that niche.
haven't played it yet, but i second the multiplayer excitement. heboris/lockjaw is a pretty amazing combo that lacks only 1 thing as far as i'm concerned: netplay. if you can get SRS/ARS selection, 20g, and netplay, your game will be very popular around here... edit: you never having seen hold is not a great sign... *sigh* ok, well i'm trying it, or trying to, my laptop's numpad (on a toggle that switches out jkl,uio,789) is not being detected--perhaps you could make a left hand centric build (asd,qwe with jkl for rotations is my ideal) or, not to imply that you aren't probably on top of it, implement key config asap. that being said i got three O's in a row while fiddling--how does your randomizer work?
Throw this into the keyconfig directory. This will now use ASD for the soft movements, QWE for the hard movements, and JKL will do the various rotations. I'll try to make a key config available soon. It gets a random seed based off the current system time, and then uses that to generate random numbers using the java Random class. The Block Generator class is incredibly simple, so I'll quote it below: Code: import java.util.*; public class BlockGenerator implements Blocks { Random rand; public BlockGenerator() { long seed = System.currentTimeMillis(); rand = new Random( seed ); } public BlockGenerator(Random r) { rand = r; } public int nextBlock() { return Math.abs( rand.nextInt() ) % BLOCK_COUNT; } }
i wrote an autohotkey script to change the controls to something manageable. your hard drop is a firm drop but there is no way to lock after using it. this means you have to stop and wait for the next piece to show up on the screen between every move--that alone makes things very very frustrating. horizontal movement is inconsistent, seemingly as a result of the complete lack of DAS. this makes misdrops ultra common. there are absolutely no wall kicks... and no lock delay, i mean, i guess there is some because of the way that hard drop works, but it is really weird and makes it feel like all the "sticky" tetris of old. the randomizer gives 2 or even 3 of the same pieces in a row constantly. on a lighter note: 10 is the highest lvl and it isn't nearly fast enough to be the end of the game! immediate: 1. go play lockjaw, go play heboris, and, though i never thought i'd say this, go play tetriszone. 2. decide on a ruleset/color scheme or at least fix the existing colors (the sega colors go along with at least the way i think you intend your rotation to work.) Code: [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][x][x][x][x] [ ][ ][ ][ ][ ][ ][o][o][ ][ ] [ ][ ][ ][ ][ ][ ][o][o][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ][x][ ] [ ][ ][ ][ ][ ][ ][ ][ ][x][ ] [ ][ ][ ][ ][ ][ ][o][o][x][ ] [ ][ ][ ][ ][ ][ ][o][o][x][ ] this move doesn't work, and probably should...
that's because lockjaw and heboris don't have the word "tetris" associated with them in any way as you improve your game i would suggest changing the name so you don't draw any negative attention. it would be a shame if you spent a lot of time building a good netplay game, only to have it shut down.
aside from playing the mentioned games, I would also recommend reading up on the Tetrisconcept wiki, as it contains definitions for many of the rather obscure technical terms that are commonly used in discussion. eg. the guideline, Sega/TGM rules, ARS, SRS, DAS, ARE, IRS, IHS, soft/hard/firm(sonic) drop, zangi-moves, lock delay, wallkicks(twists), lock reset rules, randomizer algorithms, initial stances, free speed/forced speed, millisec-based/frame-based, etc etc etc.
Thanks to everyone for the feedback. I'm headed out to work now, but when I get home tonight I should be able to start implementing some of the things that were brought up. Within the framework I have most of it sounds trivial to implement, especially with that tetris WIKI outlining how things should be done. In the meantime, keep any criticism/comments coming. I appreciate it. It's just a shame I came across this forum this late into my development. At least it wasn't even later.
Your code implements what Lockjaw calls the "Memoryless" randomizer, as seen in most older (pre-2001) Tetris products. More recent Tetris products tend to use a randomizer more like that used in card games: shuffle the "deck" of 7 tetrominoes and then deal each into the next piece queue. Mr. Rogers calls it the "Random Generator"; Lockjaw calls it "7-piece Bag". I don't have JDK installed right now, but here's some untested code: Code: public class TTCRandomGenerator implements Blocks { Random rand; int[] deck; int cardsLeft; public BlockGenerator() { this(new Random(System.currentTimeMillis()); } public BlockGenerator(Random r) { deck = new int[BLOCK_COUNT]; cardsLeft = 0; rand = r; } protected void reshuffle() { cardsLeft = BLOCK_COUNT; for (int i = 0; i < BLOCK_COUNT; ++i) { deck[i] = i; } } public int nextBlock() { if (cardsLeft == 0) { reshuffle(); } if (cardsLeft > 1) { int r = Math.abs( rand.nextInt() ) % cardsLeft; int swap = deck[r]; deck[r] = deck[--cardsLeft]; return swap; } else { return deck[0]; reshuffle(); } } } Oh, and if you want to implement replays, you're going to have to make the randomizer classes implement Serializable too.
I haven't tried yours yet, but let me say that figuring out whether you want to make it a classic-style or modern-style game (or give options for each) will be a major issue. When people are talking about the lock delay, ARE, and 20g, the assumption of a modern-style game is made. It can go either way, but it's your call; a few considerations in each case: If you want to go classic-style, that'd mean a lock delay of zero or very close to it. That makes any movements which occur faster than the player can control the piece impossible; consider trying to make a piece fall 2 blocks per frame (2g) with this setup. It wouldn't work if the game is taking input at 60 Hz. Hence these games top out at 1g (a drop of one block per frame), which, if there's good control (such as a DAS that's as fast as the framerate), is not going to challenge any of us. However, if you make the game run smoothly at a higher rate, it would be possible to still make it difficult and classic-style, just at, say, 85/100/120+ Hz. If you want to go more modern-style, well, first you'll have to familiarize yourself with high-speed play. That's the big issue since, with a significant lock delay, something like 20g is a necessity. I won't say as much about this one since everyone else will, except there's one big point: there are a LOT of ways to do lock delay. The three big ones that come to mind over here are resetting the lock timer on any movement/rotation ("infinite spin"; not a favorite here), Arika's resetting the timer when the piece drops, and only resetting the timer for the next piece. Last thing: tepples brought up how randomizers tend to go in Tetris games, but Arika has its own system; you'll need to look up that one, too. It's somewhere between the two and has an adjustable parameter that you can have fun with; the original TGM uses 4 and the games since use 6. If you wanted to do something like the original Tetris's system, just slightly nicer, even using Arika's system but with the parameter as 2 would work...
Well, my gamelogic code is running on a different thread than the rendering code. The GameLogicjust does what it does, and every once in a while the rendering engine comes along and say "hey what do you look like?" (in a thread safe manner of course). So it seems like implementing 20G wouldn't be a difficulty here, as long as none of my game logic calculations are too intensive, which I'm certain their not.
And I just did some testing, incredibly fast falling blocks does absolutely nothing. I've got it refreshing every millisecond and the CPU isn't even being taxed. Edit: and this reveals all the flaws in the current motion of my blocks. I'll be implementing wall jumps and whatever else I can do tonight. If I get anything of interest done I'll post it up for some feedback, if not tonight then in a few days. Thanks again to everyone for helping out.
That's another design philosophy issue: whether to base the system on milliseconds and have the framerate depend on processor speed, or lock it at a fixed 60 frames per second. While at first sight, more frames per seconds seems better, a fixed framerate has the advantage of affording consistency in individual frame-level controls to the user. PC-based games often use a msec-based variable framerate model, and well-recognized console and arcade games like Tetris DS and TGM use the fixed framerate model.
Well, I'm not against fixed framerates, I just don't like having the two seperate entities entwined. The rendering engine should be doing what it's doing, and the game logic engine should be doing what it's doing. A slow down in the rendering engine should not affect the game engine.
It doesn't need to. Hane an interupt that happens 60 times a second. Each call, it increments a variable. Your game logic loop checks for non-zero, and when it is non-zero, it processes a frame and decrements the counter. Whenever the counter is 0 (which it will be unless the game is really struggling), it just does nothing (this may include giving CPU time to other tasks). If you do this, then you will probably see it doing very little for a lot of the time. Oh, and what Needle said is generally correct, but I know of at least one "PC-based" game that uses a fized framerate.
Yeah, hence "often". Heboris and Lockjaw both use 60fps. Again, this a an issue of philosophy - as alien as it might sound, for some people, the game logic should slow down when the processor is overloaded. (Obviously this doesn't fare well in things like multitasked environments, games with heavy load, or games where motion can be sliced into infinitely small units.) I guess PC-based games use msecs and independent logic/video more often due to the platform's nature of having hardware with varying processing power. Caring about slowdown comes less into consideration when one is developing on a console or arcade hardware running on one fixed hardware configuration. When it does happen, slowdown also seems to be more tolerated on 2D arcade/console hardware - in fact, some modern shoot-em-up games simulate slowdown on purpose as part of the intended game design, to allow the player more time to think when many bullets are onscreen. Not saying that fixed 60fps is better; just pointing out that both are valid methods with their own philosophies.
Alright, I some of the basic stuff implemented. Block Ghosts Wall Jump (no floor jump yet) SRS Rotation. Firm Drop Locking I've also set level 6 to the fastest the game can render at: 1 block per millisecond. I don't know how fast this is relative to 20G yet, but it's currently my internal max. I'd have to change some code up to go faster, but it's certainly doable if we need it. I definitely want to support 20G. Clearly level 6 wouldn't be this fast, I just put it there for easy access. Still no Key Config, GUI code always takes me a while to write, so I'm putting that off until I have the game play up to some decent standard. It should only be a few more days, hopefully today took a big chunk out of it. In the next few days I hope to implement a better delay system, a simple key config, and whatever other game play issues there are. Once I get a basic configuration setup that people are happy with I'll go on to creating the GUI and the networking stuff. Once the GUI is up and running you guys will have a better idea about what's configurable and what isn't, and can hopefully tell me what else needs to be implemented to cover all the different game styles. Does anyone know if 1 row per millisecond is at least as fast as 20G? I don't mind changing code around, but it would be nice if this is fast enough. I also changed the buttons around. It uses the arrow pad now, down for soft drop, up for hard (firm?) drop. Up again when it's sliding to lock the block into place. Right now the delay system is all haywire. I'm going to completely changing it tomorrow, so just ignore it's badness tonight. V0.6.01 Matt: I'm not sure if you saw my previous post, but you can use this key config. It's setup the way you like. Just put it in the /keyconfigs folder and it will load. Also: I've been trying to think of a name for this forever. If anyone has any suggestions I'm glad to hear them.
I'll have to look into this more. Without thinking about it too hard, I'm pretty sure I can setup my current independent system to simulate a fixed FPS system like you're describing, so if it's really wanted, I should be able to do it. Hell, I could probably even make it an in-game option.
i use a fixed timestep for the physics and game logic. but but because rendering speed may vary, i implemented the accumulator scheme: http://www.gaffer.org/game-physics/fix-your-timestep/ this is a very error prone way to do things. dynamic time step is sometimes really hard to debug (over / underflows, divisions by zero, whatever can happen if your delta-t is out of bounds) only disadvantage of a fixed timestep & loop accumulator is that you need a high-resolution timer.