JSTris

Started by jezevec10, December 06, 2014, 03:21:55 PM

Previous topic - Next topic

errata

Hey, jezevec10

Great work on on the site! I'm curious about the replay format. I've looked around a bit and I can't seem to find anything about it. Is it documented somewhere?

jezevec10

#136
Quote from: errata
Hey, jezevec10

Great work on on the site! I'm curious about the replay format. I've looked around a bit and I can't seem to find anything about it. Is it documented somewhere?
It is a custom format for jstris and currently has no documentation available. It mainly consists of a list of timestamps and actions that happened at that time. This list is encoded in a bitstream where timestamp is 12bits long and action code 4bits long. The timestamp overflows every ~4seconds, but there is always at least one action in this time span. This stream is prepended with json metadata and everything is compressed using lz-string. The piece sequence is restored from the PRNG seed, the algorithm used is called Alea.

Let me know if you need more detailed description. This is just a short overview of how the format works.

errata

Quote from: jezevec10
Let me know if you need more detailed description. This is just a short overview of how the format works.
Thank you for what you've given me so far, I can probably reverse the format now but if you have any more help to give I'd appreciate it. I can unpack the json ok but I don't understand it all.

{
  "c":{
    "v":3,
    "softDropId":4,
    "gameStart":1533871560737,
    "gameEnd":1533871632731,
    "seed":"byhaug",
    "m":1,
    "bs":2,
    "se":1,
    "das":83
  },
  "d":"ADMS..."
}


v is the replay version, das, seed, gameStart and gameEnd are self explanatory but the rest I'm unclear on? When I coerce the d data into an int16 array by ASCII value that seems to produce something that has 16 bit wide fields but I don't understand the data inside them. There seem to be too many zeroes? I end up getting 6-7 bits worth of data every 16bit wide field and the rest is zeroes. Any help you're willing to give will be appreciated.

I'm trying to build a replay analyzer fwiw.

k_rakko

Quote from: errata

v is the replay version, das, seed, gameStart and gameEnd are self explanatory but the rest I'm unclear on? When I coerce the d data into an int16 array by ASCII value that seems to produce something that has 16 bit wide fields but I don't understand the data inside them. There seem to be too many zeroes? I end up getting 6-7 bits worth of data every 16bit wide field and the rest is zeroes. Any help you're willing to give will be appreciated.

I'm trying to build a replay analyzer fwiw.

"d" is a BASE64 encoded binary data. You can use online converter at here (base64 to binary). Note that "/" is escaped in json so replace "\/" with "/" before you use converter.

Basically, replay data is saved in following format.
timestamp (12 bits long) + action code (4 bits) +next timestamp + action code + timestamp ......

You can read time stamp to use this.
0.016 * (first 8 bit) + 0.001 * (following 4 bits)

You can use this table to decode action code.
{MOVE_LEFT:0,MOVE_RIGHT:1,DAS_LEFT:2,DAS_RIGHT:3,ROTATE_LEFT:4,ROTATE_RIGHT:5,ROTATE_180:6,HARD_DROP:7,SOFT_DROP_BEGIN_END:8,GRAVITY_STEP:9,HOLD_BLOCK:10,GARBAGE_ADD:11,SGARBAGE_ADD:12,REDBAR_SET:13,ARR_MOVE:14,AUX:15}


For example, to decode 40L world record by MicroBlizz, you can get binary data start at 00000111 1000 0111 00001110 11100111 ....

This means 0111 = code 7:HARD_DROP at
00000111 * 0.016 + 1000 *0.001 = 7*0.016 + 8*0.001 = 0.120 sec
and another hard drop at
14 *0.016 + 14 * 0.001 = 0.238 sec.

In addition, it is a little difficult to decode action code 11:GARBAGE_ADD. You can find additional data after action code.(5 bits of number of garbage line and 4 bits of position of hole.)

It is too hard for me to teach you how to decode data after 0.016*256 sec. Just use magic number 4.094 sec.

Good luck.
I am praying for your success with you project.



errata

#139
Quote from: k_rakko
"d" is a BASE64 encoded binary data.

Ahahah oh my god, this is why you don't program late at night. I thought it was base64 but for some reason i couldn't get window.atob() to work last night. Turns out I had truncated the last letter off the end of the string. This is very helpful, I'm now able to comfortably extract everything I need for 40 line replays. Thanks!


{time: 0.120, moveID: 7, move: "HARD_DROP"}
{time: 0.238, moveID: 7, move: "HARD_DROP"}
{time: 0.277, moveID: 0, move: "MOVE_LEFT"}
{time: 0.350, moveID: 2, move: "DAS_LEFT"}
{time: 0.405, moveID: 7, move: "HARD_DROP"}
...


I guess the only thing I'm missing is how to get alea to return the right values. I think I can work it out from the website source. Thanks so much for the help guys!

jezevec10

#140
Quote from: errata
v is the replay version, das, seed, gameStart and gameEnd are self explanatory but the rest I'm unclear on?
  • softDropId - this will be needed to make the softfdrop work in the replays. It's because users can set different softdrop speed. Soft drop step is a normal GRAVITY_STEP anywhere inside two SOFT_DROP_BEGIN_END actions. Faster softdrop speeds have more Y steps per one gravity step. The decode table is here (time property not relevant for the purpose of replays): [{id:0,time:0.05,steps:0},{id:1,time:0.008,steps:0},{id:2,time:0,steps:1},{id:3,time:0,steps:2},{id:4,time:0,steps:20}]
  • m - here is encoded the game mode and submode of the replay. If you want to play just sprint games, from this you can set number of lines remaining: {1:40,2:20,3:100,4:1000}
  • bs and se - block skin and sound effect set, not needed
  • das - DAS value the game was played with, it is not needed in v3 replays
Quote from: errata
I guess the only thing I'm missing is how to get alea to return the right values. I think I can work it out from the website source. Thanks so much for the help guys!
I've created a simplified version of the block randomizer which shows how to use alea to obtain the block queue.

var blockRNG=alea(seed);                 // seed the randomizer
var bag=["I","O","T","L","J","S","Z"];   // block indices
function getBlock(){
  var index = Math.floor(blockRNG() * bag.length);     // random index in the current bag
  var rand = bag.splice(index,1)[0];                   // get the block and remove from the current bag
  if(bag.length === 0)bag = freshBag.slice(0);         // refreshes the bag to the original state (above)
  return rand;
}

The block queue is constructed by subsequent calls of getBlock(). Note that for all practice modes, if the queue starts with s/z the starting block switches its position with either 2nd or 3rd block in the queue (whichever will first avoid s/z being the first block).

jezevec10

Updated:
  • Ultra mode
    • A practice mode where the goal is to gain the highest score possible in 2 minutes
       
    • The standard scoring system is used
       
    • Leaderboards and replays are available
       
    • The leaderboards include a new statistic, Points Per Block (PPB), which indicates the scoring efficiency of a game
  • Speed Limit option for multiplayer games
    • The game will reject the hard drop inputs if you are going over the specified PPS speed limit
       
    • You can create rooms with a custom speed limit (a new option in the "Simple" room configuration tab)
       
    • The "Main room" has been replaced with the "Speed Limit room", which has a fixed speed limit of 1.5PPS
       
    • PPS is calculated differently in the rooms which have a speed limit set (current pps is used instead of game-average pps)
  • Improved the list of rooms
    • The list is divided into two sections - static rooms at the top and custom rooms
       
    • Both sections are sorted by an amount of games played, so the most used rooms are always at the top
       
    • If a room has a speed limit, a special icon is displayed next to it's name
  • Scoring playlist in the replays
    • Under each replay there is a playlist with timestamps of any moves in the replay that generate score
       
    • By clicking on an item, the replay will rewind to the spot where the move is
       
    • The list can be filtered by the check boxes next to it (e.g. only perfect clears can be listed)

PuyoUltimate

This game is awesome now for some reason i play jtetris way more than Tetris Friends

Okey_Dokey

#143
Looks good  

I like that you get that message on red background when you play too fast in the speed limit rooms. I think the game should ignore all your inputs during the first 0.5 seconds of that message - or at least the hold inputs. If you try to hold the next piece, you end up with the wrong piece after a failed harddrop attempt. You could also add a speedometer in speed limit rooms. I mean just a Pieces Per Minute number (rounded down to next integer) on the position/location where you see the remaining lines (and time) in Sprint (and Ultra respectively). That number could become red, if you are above the limit, and orange, if you're near it.

I think 1.5 pieces per second is a little too less for the default speed limit room. Most players will go above it from time to time (note it's max speed and not average speed). I suggest increasing the limit a litte (e.g. 1.7 pps) or adding a AutoRepeatRate limit to that room, too.

Just for the sake of naming consistency I have to point out that you use "blocks", "blocks per piece" and "pieces per second" in the leaderboard statistics. So one time you use block and the other time you use piece for the same thing. Not that PPP (points per piece) would be a better abbreviation.

I like the scoring list in the replays. I guess this also simplified debugging the Ultra mode. I think 3000 points per Perfect Clear is a little too much. For comparison, older official games often didn't reward PCs in Ultra (and Marathon) and newer official games will hand out 2000 points at maximum (depending on the amount of lines you clear). In official games, T-Spin Triples are the most effective way to play Ultra and that's 2400*4/3 = 3200 points per 4 lines (without drop points). If you clear 4 lines with a Perfect Clear, you'll usually get another 600 points from Singles, Doubles and combos - and around 100 more drop points because you stack lower. So I would say, 2600 2700 points per Perfect Clear would be appropriate - that's slighty more effective than TSTs (3200 - 600 = 2600). Also note that there are some 14 lines T-Spin loops that end in a Perfect Clear.

Anyway, I think it would be a good idea to have a second Ultra mode where you receive 1 garbage line every 10 pieces. This would stop people from using looping techniques. Such a garbage Ultra mode could also last a little longer, 3 minutes perhaps.

Haven't checked it but the last time I played multiplayer, the expanded room statistics for the last round disappeared when a new round started (or I wasn't fast enough to click that button and the statistics were already gone). There must be a better way. I like to check the speed of my opponents - I think that's more important than the number of lines sent / received you see in the basic statistics.

XaeL

Quote from: Okey_Dokey
Haven't checked it but the last time I played multiplayer, the expanded room statistics for the last round disappeared when a new round started (or I wasn't fast enough to click that button and the statistics were already gone). There must be a better way. I like to check the speed of my opponents - I think that's more important than the number of lines sent / received you see in the basic statistics.

I think one of these could be a solution:
1) detailed stats for previous game was displayed below chat
2) detailed stats for current game shown live
3) countdown timer for next game, minimum 5 seconds.

#discuss




QuoteLike many setups here, it is useful if your opponent doesn't move and you get 4 Ts in a row.

Lucho

Quote from: XaeL

3) countdown timer for next game, minimum 5 seconds.

#discuss
I agree with this, I feel like it will encourage people to talk a bit more.

And how about adding a little colour and shapes to the site ? Maybe that keeps the newcomers around  
[div align=\\\"center\\\"][spoiler]
Funky Ruskie[/div][div align=\\\"center\\\"] [/div][/spoiler]

Okey_Dokey

#146
Yeah, it would be a good idea to make the "new game" button stop working in the first 3 or 5 seconds after a game has ended (button is greyed out and counts down, game end = when 2nd place tops out).

This post is not a suggestion. I just wanted to link a few Ultra replays where players use different strategies. The PPB stat makes finding interesting replays easy. You can also find all Ultra replays by a user by editing the name in the following link. First number is the final score, second number is pieces per block rounded down to next integer.
  • 114,929 Opium aka OnePunMan (296 ppb): Currently, the best score on Jstris achieved with ZT Stacking. I think Firestorm got 130,000 points in NullpoMino. As a note, if a replay is around 280 ppb, then it's usually ZT Stacking
  • 101,751 Reincarnation (260 ppb): I think that's an Opium multiple. It starts with Perfect Clears, then goes into freestyle and then Infinite TST.
  • 93,014 cloak aka qmk (299 ppb): cloak proves that it is possible to get 300 points per block with pure freestyling. In the very end, he loses b2b bonus once and places 2 T pieces without a T-Spin. Such a noob.
  • 90,581 z2sam (209 ppb): The replay with the worst PPB near the top of the leaderboard and that's because of 4-wide. I am very sure z2sam can get 100k+ points with ZT Stacking.
  • 90455 ten423p aka whipemerald (247 ppb): whipemerald starts with freestyle but also does some Perfect Clears midgame.
  • 76,312 Okey_Dokey (326 ppb): That's basically the highest PPB you can get with Infinite TST. The stack is pretty low in the end and I cleared T-Spin Triples only.
  • 59,002 penguin (406 ppb): This should be a Captivate multiple proving that 400 points per block are possible with Perfect Clears. It's 15 PCs within 58 lines (one 2-lines PC) and idling in the last seconds.
  • 49,896 rukyamac (317 ppb): That's the BT Cannon into C-Spin 14-lines Perfect Clear loop. The effectiveness of that technique is slighly above that of Infinite TST (but only 5 points per block or so).

jezevec10

Updated:
  • Map downstack mode
    • A practice mode where the goal is to downstack / solve a map created by other players
    • Because everyone can create a new map, this mode can be used to practice downstacking of different stacks than just a cheese like in cheese/survival modes. The block queue can be predefined by the map author so the mode can be used also for quizes/spin practice.
    • Select the map to play on from the list of maps (in the main menu) and play by clicking on the map preview
    • Map creators can set different rules for each map
      • The game is either finished by clearing all map bricks or by doing a Perfect Clear
         
      • The block queue is either random or statically predefined by the map author
         
      • Possibility of other map settings (you can suggest here)
    • Each map has its own leaderboard and replays
    • Every registered user can design own map by using a map drawing tool available in the menu
    • The players can give upvotes and downvotes to maps, the default sorting is similar to Reddit. Feel free to create new maps!
  • Information about a Personal Best after a game
    • If you achieve a new personal best on your account, you are now notified about it with a message like this
  • APM and PPS of the last games added to the stats on user profiles
    • The displayed values are averages over the last 10 multiplayer games
This is the final large update of this summer, if you liked any of the changes made this year, you can make a donation so the game server can keep running - read more here.

Goofball

Not a bug by any means, but a request:
Could there be an option to customize the positioning of the visual layout at all?

In my case, I'd REALLY love to be able to have a different positioning of the piece previews, as the way I visually process things has the default layout driving me absolutely batty since I can't keep proper track of the topmost piece preview while remaining focused on my field, and consequently needless mistakes are made, or I have to slow down a great deal.

Perhaps even something as simple as this?:
[attachmentid=1202]

It would improve my quality of JStris life IMMENSELY!


Also, is there anywhere that has a comprehensive list of the game commands?

Okey_Dokey

#149
Quote from: GoofballCould there be an option to customize the positioning of the visual layout at all?
This is actually possible with a TamperMonkey (Chrome) / GreaseMonkey (Firefox) script:

// ==UserScript==
// @name         Jstris Mods
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://*.jezevec10.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    window.addEventListener('load', function(){

        // Jstris Custom Background Image
//        document.head.getElementsByTagName("style")[0].innerHTML="";
//        document.body.style.backgroundImage="url('https://media.discordapp.net/attachments/
            360554528556449795/361706190406680576/d29d4205-1f9e-4c85-8a5b-3f573e55b5f4.png')";
//        document.body.style.backgroundSize="100%";
//        document.getElementById("app").style.backgroundColor="rgba(0, 0, 0, 0.8)";
//        document.getElementById("app").style.height="1000px";

        // Jstris Next Piece Queue Change
        document.getElementById("rstage").style.marginTop="96px"; // 48,72,96
        document.getElementById("holdCanvas").style.marginTop="96px"; // 48,72,96
        document.getElementById("queueCanvas").height="160";
        document.getElementById("sprintInfo").style.marginTop="136px";

        // Jstris Block Skin Change
        loadSkin("https://i.imgur.com/G6WbXoD.png",32);
//        loadGhostSkin("https://i.imgur.com/OvH7LA4.png",36);
    });
})();

Lines starting with // are commented out (not applied). rstage marginTop influences how far the preview queue is moved down. holdCanvas marginTop does the same thing with the hold piece. queueCanvas height influences how many pieces you see. sprintIngo marginTop influences the position of the info showing the remaining lines in sprint and the remaining time in Ultra. The script with the values above will make the game look like that (loadSkin loads a Puyo Puyo Tetris skin):

[!--ImageUrlBegin--][a href=\\\"https://i.imgur.com/7RmMaJh.png\\\" target=\\\"_new\\\"][!--ImageUrlEBegin--][img width=\\\"500\\\" class=\\\"attach\\\" src=\\\"https://i.imgur.com/7RmMaJh.png\\\" border=\\\'0\\\' alt=\\\"IPB Image\\\" /][!--ImageUrlEnd--][/a][!--ImageUrlEEnd--]

PS: the code with loading a background image only works sporadically for me when activated.

Quote from: GoofballAlso, is there anywhere that has a comprehensive list of the game commands?
There's the /help command which should tell you what other commands exist.