<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Play Pip</title>
    <description>The latest articles on DEV Community by Play Pip (@playpipio).</description>
    <link>https://dev.to/playpipio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4194469%2F58c61a3b-8390-4d76-a81e-24c707824377.png</url>
      <title>DEV Community: Play Pip</title>
      <link>https://dev.to/playpipio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/playpipio"/>
    <language>en</language>
    <item>
      <title>A poker night with friends, online, with nothing to settle up</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/a-poker-night-with-friends-online-with-nothing-to-settle-up-24hd</link>
      <guid>https://dev.to/playpipio/a-poker-night-with-friends-online-with-nothing-to-settle-up-24hd</guid>
      <description>&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;One person opens a private room on Pip and sends the others a link. Up to eight of you sit at one Texas Hold’em table, with your cameras and mics on if you want them. The host needs the membership. Everybody else needs a free account and the link.&lt;/p&gt;

&lt;p&gt;The chips are play chips. Nobody owes anybody anything at the end, which used to be the hardest part of the evening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who deals
&lt;/h2&gt;

&lt;p&gt;Our server does. It shuffles, deals, and sends each player their own two cards and nobody else’s, until a showdown turns them over. Nobody has to hold a deck up to a webcam and read out the flop. How that works, and the test that checks it, is in &lt;a href="https://playpip.io/blog/your-cards-stay-on-the-server" rel="noopener noreferrer"&gt;Your cards stay on the server&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the host sets
&lt;/h2&gt;

&lt;p&gt;Before the first hand, the host picks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the seats, from two to eight;&lt;/li&gt;
&lt;li&gt;the stake, one of the ladder’s, which sets the chips and the blinds;&lt;/li&gt;
&lt;li&gt;starting chips: standard, deep or very deep;&lt;/li&gt;
&lt;li&gt;blinds: slow, normal, turbo, or fixed so they never rise;&lt;/li&gt;
&lt;li&gt;time to act: 15, 30 or 60 seconds;&lt;/li&gt;
&lt;li&gt;what happens when somebody leaves;&lt;/li&gt;
&lt;li&gt;whose chips: from the Roll, or just for fun.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everybody at the table can read the rules. Only the host can change them, and only before the deal. The game is a sit-and-go: the same stack each, the blinds climb unless you fixed them, and the last player with chips wins. The rules live in &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/multiplayer/room.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/multiplayer/room.ts&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whose chips
&lt;/h2&gt;

&lt;p&gt;The Roll is the bankroll you carry up Pip’s ladder. &lt;em&gt;From the Roll&lt;/em&gt; takes the buy-in from each player’s Roll and pays the winner the buy-in times the seats. &lt;em&gt;Just for fun&lt;/em&gt; takes nothing and pays nothing.&lt;/p&gt;

&lt;p&gt;Either way the chips are never for sale, and nobody at the table sees anybody else’s Roll or rank. The membership changes nothing once the cards are dealt. A host who pays plays the same cards as a friend who didn’t.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faces and voices
&lt;/h2&gt;

&lt;p&gt;Both are off until you tap them. Turn the camera on and your face takes your seat where the avatar was. Turn the mic on and the room hears you. The picture is 320 by 240 at 15 frames a second, which is enough to see somebody trying not to smile.&lt;/p&gt;

&lt;p&gt;Video and voice go between players’ browsers; the room server passes on the messages that connect them. Tap anybody’s seat to mute them or hide their camera, for you only. Report and block are on the same sheet. A blocked player’s camera and voice stop reaching you, and they are not told.&lt;/p&gt;

&lt;h2&gt;
  
  
  When somebody gets up
&lt;/h2&gt;

&lt;p&gt;Stand up mid-game and the host’s rule decides. With &lt;em&gt;Keep their seat&lt;/em&gt;, your chips stay and your hands fold until you sit back down. With &lt;em&gt;They’re out&lt;/em&gt;, you are out after the hand in progress, which is how some poker nights have always ended.&lt;/p&gt;

&lt;p&gt;Short of people? Before the deal the host can fill empty chairs with Pip’s regulars, the same characters you meet on the ladder.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn’t do
&lt;/h2&gt;

&lt;p&gt;It is Hold’em only. There is no real money and no way to add any. A room is cleared half an hour after its game ends, so there is no record of who won last week. You will have to remember that yourselves, and you will.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;Opening a room is part of the &lt;a href="https://playpip.io/membership?for=multiplayer&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;, and that page says what else is in it. Joining a friend’s room is free, and so are the ladder, the Rail, the Daily and the freeroll.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>web</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How often both your cards play in Hold’em</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Thu, 15 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/how-often-both-your-cards-play-in-holdem-39p5</link>
      <guid>https://dev.to/playpipio/how-often-both-your-cards-play-in-holdem-39p5</guid>
      <description>&lt;h2&gt;
  
  
  The count
&lt;/h2&gt;

&lt;p&gt;In Hold’em you hold two cards, the board shows five, and your hand is the best five of the seven. Nobody makes you say which five. So we counted how often your own two make it in.&lt;/p&gt;

&lt;p&gt;Every way to deal two hole cards and a five-card board from one deck is 2,809,475,760 deals. For each one we took the best hand you can make and asked which of your cards it needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both of them: 1,324,680,512.&lt;/li&gt;
&lt;li&gt;One of them, either will do or only one helps: 1,347,370,964.&lt;/li&gt;
&lt;li&gt;Neither, because the board alone is as good: 137,424,284.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So both your cards play in a little under half of all deals, and one card does the work slightly more often than two. In about one deal in twenty, your cards play no part at all.&lt;/p&gt;

&lt;p&gt;These are deals to the river with nobody folding. Real hands fold, and the ones that get to a showdown are not a random sample. It is a count of what the cards can do, not of what players do with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the board plays
&lt;/h2&gt;

&lt;p&gt;You 8♥ 2♣ · Board 9♠ 10♥ J♦ Q♣ K♠&lt;/p&gt;

&lt;p&gt;You have a straight. So does everybody else still in the hand. Your eight makes a straight too, just a worse one, so it sits out. When the board is your best hand, every other player has at least the board as well, and the most you can win is a share.&lt;/p&gt;

&lt;p&gt;You 3♣ 3♦ · Board A♠ A♥ K♦ K♣ Q♠&lt;/p&gt;

&lt;p&gt;A pocket pair that does nothing. Aces and kings on the board, the queen as the kicker, and your threes are the third pair, which a hand of five has no room for. &lt;a href="https://playpip.io/learn/three-pair-in-texas-holdem" rel="noopener noreferrer"&gt;Three pair&lt;/a&gt; has a page of its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  When one card does it
&lt;/h2&gt;

&lt;p&gt;You A♥ 7♣ · Board K♥ 9♥ 5♥ 2♥ J♠&lt;/p&gt;

&lt;p&gt;Four hearts on the board and the ace of hearts in your hand: an ace-high flush. The seven of clubs does not come into it. Swap it for any card but a heart and the hand is the same.&lt;/p&gt;

&lt;p&gt;You 6♠ 7♠ · Board 8♠ 9♦ 10♣ K♥ 2♦&lt;/p&gt;

&lt;p&gt;Here it takes both. Eight, nine and ten on the board, the six and seven in your hand, and neither card makes the straight without the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  More than one right answer
&lt;/h2&gt;

&lt;p&gt;You K♥ 9♦ · Board 9♠ 10♥ J♦ Q♣ 3♠&lt;/p&gt;

&lt;p&gt;The king makes a nine-to-king straight, and there are two nines to start it with, yours and the board’s. Both fives are the same hand. Neither is more right than the other.&lt;/p&gt;

&lt;p&gt;Seven cards can be cut down to five in twenty-one ways, and usually one way is best. Of the 133,784,560 possible sets of seven, 3,079,988 have two or more that tie, about one in 43. Most of them, 2,386,100, are straights with a pair inside them like this one. Another 617,760 are three pair where the third pair is also the best kicker, so either card of it will do. The last 76,128 are full houses and fours of a kind with a spare card to choose between.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we counted
&lt;/h2&gt;

&lt;p&gt;A short program dealt all 133,784,560 sets of seven and split each one every way it can be split into two hole cards and a board, which takes about a minute. It ranks hands with an evaluator of its own, written for speed, so it is not the code that settles Pip’s pots. Two checks tie it to that code. Its count of each hand type over seven cards matches the standard table exactly. And 400,000 random deals through Pip’s evaluator came out at 19,568 board, 191,959 one card and 188,473 both, against 19,566, 191,832 and 188,602 expected from the full count.&lt;/p&gt;

&lt;p&gt;The full count is too slow for the test suite and is not pinned by it. &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/whichFivePlay.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/whichFivePlay.test.ts&lt;/code&gt;&lt;/a&gt; holds the rest: the three rows add up to every deal, and each hand in this post plays the cards it says it does, by Pip’s evaluator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Which five play?&lt;/em&gt; is a drill: seven cards, tap the five that count. It is graded by ranking all twenty-one fives, so when two tie, either one is right. It is in the &lt;a href="https://playpip.io/membership?for=drills&amp;amp;drill=which-five-play&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;. &lt;em&gt;What have you got?&lt;/em&gt;, which asks you to name the hand rather than point at it, stays free for everyone, as does &lt;em&gt;Which hand wins?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
    <item>
      <title>Five-Card Draw: what the number of cards gives away</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Wed, 14 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/five-card-draw-what-the-number-of-cards-gives-away-38gm</link>
      <guid>https://dev.to/playpipio/five-card-draw-what-the-number-of-cards-gives-away-38gm</guid>
      <description>&lt;h2&gt;
  
  
  The only tell
&lt;/h2&gt;

&lt;p&gt;In Five-Card Draw nobody shows a card until the end. There is no board. The one thing you learn about anybody’s hand is how many cards they asked for.&lt;/p&gt;

&lt;p&gt;At Pip’s Draw tables, The Parlour, the regulars all decide what to throw by the same short rule, &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/ai/draw.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/ai/draw.ts&lt;/code&gt;&lt;/a&gt;. A fixed rule turns that number into a read. So we dealt every one of the 2,598,960 five-card hands through it and counted what each number means.&lt;/p&gt;

&lt;h2&gt;
  
  
  None: they have it
&lt;/h2&gt;

&lt;p&gt;A regular stands pat on a straight or better and on nothing else. That is 19,716 deals, about one in 132. No regular stands pat on a bluff, so when one does, believe it.&lt;/p&gt;

&lt;h2&gt;
  
  
  One: two pair, or a draw
&lt;/h2&gt;

&lt;p&gt;One card covers three different hands. Two pair throws its odd card: 123,552 deals. Four to a flush throws the fifth: 110,940, and 34,320 of those broke up a pair to do it. Four in a row throws the fifth too: 60,480.&lt;/p&gt;

&lt;p&gt;So we dealt the card too: every one of the 47 left, for each of those deals. A little over one in seven ends with a straight or better, the full houses included. About one in three ends with nothing at all, not even a pair. Two pair is still the likeliest thing to come over at the end. One card deserves some respect. Not a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two: three of a kind, every time
&lt;/h2&gt;

&lt;p&gt;Only trips draw two. 54,912 deals, and nothing else in the rule asks for two. Of all the numbers it is the one that tells you exactly what you are up against.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three: a pair
&lt;/h2&gt;

&lt;p&gt;The common one, 1,057,224 deals, about four in ten. The rule keeps any pair, deuces included, and throws the rest. Even a pair of twos beats drawing four to an ace, which is what the next number is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four and five: nothing
&lt;/h2&gt;

&lt;p&gt;Four cards means an ace and nothing to go with it: 466,560 deals. Five means not even that: 698,880, more than one deal in four. A regular holding K-Q-8-6-3 throws the lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one coin flip
&lt;/h2&gt;

&lt;p&gt;A pair at the end of four in a row, say 5-6-7-8-8, could go either way. The rule keeps the run and draws one 35 times in 100, and keeps the pair and draws three otherwise. It comes up in 6,696 deals, and it is the only spot where the number can mislead you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not chase
&lt;/h2&gt;

&lt;p&gt;An ace closes a straight at one end. J-Q-K-A fills only with a ten and A-2-3-4 only with a five, four cards rather than the eight that fill 8-9-T-J. The rule chases neither. It keeps the ace and asks for four.&lt;/p&gt;

&lt;p&gt;It also misses a pair in the middle of the run. Holding 5-6-6-7-8, it does not see the four in a row, keeps the sixes and draws three.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/playpip/pip-web/blob/main/tests/draw.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/draw.test.ts&lt;/code&gt;&lt;/a&gt; holds the rule itself, a hand for each number from standing pat to throwing all five. The counts come from one run over every deal, which takes too long for the test suite, so they are not pinned the way the rule is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;The Parlour is one of the side tables in the &lt;a href="https://playpip.io/membership?for=draw&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;, at two stakes. The page that link opens deals one hand through the draw first, each side throwing by the same rule. The ladder, the Rail, the Daily and the freeroll stay free.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Your cards stay on the server</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/your-cards-stay-on-the-server-1fbe</link>
      <guid>https://dev.to/playpipio/your-cards-stay-on-the-server-1fbe</guid>
      <description>&lt;h2&gt;
  
  
  Two kinds of table
&lt;/h2&gt;

&lt;p&gt;A single-player game of Pip runs in your browser. The deck is in the tab with you, and so are the bots’ cards. Anybody who opens the developer tools can read them. That has never mattered, because the only person you can cheat there is you.&lt;/p&gt;

&lt;p&gt;On 11 October Pip got multiplayer: private rooms you open for your friends, and quick match at the ladder’s stakes. Once there is another person at the table, a card in your browser is a card somebody can read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Face down is only a picture
&lt;/h2&gt;

&lt;p&gt;A card drawn face down is a drawing. If the browser was sent the card, the drawing is all that hides it. So a room is not dealt in anybody’s browser. Our server deals it, and keeps the deck and every hole card.&lt;/p&gt;

&lt;p&gt;Each player is sent their own copy of the table, made by &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/multiplayer/view.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/multiplayer/view.ts&lt;/code&gt;&lt;/a&gt;. The deck is emptied. Everybody else’s cards are taken out, and only how many each player holds is left, so the backs can still be drawn. Cards come back only for the players a showdown turns over. A pot won when everybody else folds shows nothing to anyone.&lt;/p&gt;

&lt;p&gt;Account ids stay on the server too. Nobody at a table needs one, and a list of them is the first thing anyone collecting accounts would want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every step, not one hand
&lt;/h2&gt;

&lt;p&gt;A test that checks one hand picked to pass tells you about that hand. &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/multiplayerView.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/multiplayerView.test.ts&lt;/code&gt;&lt;/a&gt; plays twelve seeded games instead, and at every step checks the copy each person at the table would be sent, and the copy someone watching would get. None may carry the deck, and none may carry a card its reader is not entitled to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI players
&lt;/h2&gt;

&lt;p&gt;The server does hand its bots the whole table, every card included, which is a fair thing to be suspicious of. The bots’ decisions read their own cards, the board and how everybody has bet. They guess at your hand from your betting, the same way a person would.&lt;/p&gt;

&lt;p&gt;We wanted that pinned rather than promised, so &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/multiplayerBotsSeeOwnCards.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/multiplayerBotsSeeOwnCards.test.ts&lt;/code&gt;&lt;/a&gt; makes every bot decision twice in a seeded game: once from the whole table, once from the copy a person in that seat would be sent, with the same dice. The two must match. To check the test could fail, we made a bot look at one opponent’s cards. It failed.&lt;/p&gt;

&lt;p&gt;In quick match, AI players take any seat that has not filled after about thirty seconds. Each one has an AI tag on its name plate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not do
&lt;/h2&gt;

&lt;p&gt;You cannot check a room’s shuffle. The server shuffles, and nothing yet lets you verify it afterwards. The Daily Deal is still the only thing on Pip you can deal again yourself.&lt;/p&gt;

&lt;p&gt;The members’ view of the rest of a game after you bust, every hand face up, stays at the single-player tables. At a room the server has nothing to send it.&lt;/p&gt;

&lt;p&gt;And none of this makes a room tamper-proof. It means one thing: your cards are not in anybody else’s browser until you show them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing your friends in
&lt;/h2&gt;

&lt;p&gt;A member opens a room and sends the code. Friends join free with a Pip account, camera and voice if they want them. Multiplayer is part of the &lt;a href="https://playpip.io/membership?for=multiplayer&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;. The ladder, the Rail, the Daily and the freeroll stay free.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>javascript</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A beginner beat our hardest table by betting</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Thu, 08 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/a-beginner-beat-our-hardest-table-by-betting-1kc6</link>
      <guid>https://dev.to/playpipio/a-beginner-beat-our-hardest-table-by-betting-1kc6</guid>
      <description>&lt;h2&gt;
  
  
  The hardest table
&lt;/h2&gt;

&lt;p&gt;The Main Event is the top of Pip’s ladder. Its tagline says near-optimal and merciless. The person who built Pip has played poker for two months, and was beating it, mostly by betting.&lt;/p&gt;

&lt;p&gt;That is either good news about the player or bad news about the table. We went to find out which.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bots against scripts
&lt;/h2&gt;

&lt;p&gt;Pip already had simulations that play the bots against each other. Those can never find a hole every bot shares, because the bot on the other side of the table has the same hole. So we wrote &lt;a href="https://github.com/playpip/pip-web/blob/main/scripts/exploit-sim.ts" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/exploit-sim.ts&lt;/code&gt;&lt;/a&gt;, which sits a scripted player at a real table against the real bots.&lt;/p&gt;

&lt;p&gt;The scripts play the way beginners play. One bets the pot every time it can. One calls everything. One only bets a strong hand. One shoves all-in or folds. One raises every hand it plays and bets every street it is checked to. And one plays the line most people find first: raise a decent hand, bet the flop whatever it brings, bet the turn again if checked to, and give up if anybody fights back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seven folds in ten
&lt;/h2&gt;

&lt;p&gt;When that last script raised before the flop and the flop was checked to it, the Main Event folded to a bet of two-thirds of the pot 71% of the time.&lt;/p&gt;

&lt;p&gt;A two-thirds pot bet risks two chips to win three. It breaks even if it takes the pot two times in five, which is 40%, and that holds whatever cards you have. At 71% you can make that bet with any two cards and come out ahead before anybody shows a hand.&lt;/p&gt;

&lt;p&gt;In 600 tournaments at the Main Event the script won 117. A fair share at six seats is 100.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the best bots folded
&lt;/h2&gt;

&lt;p&gt;Every bot read your hand off the chips you had put in. A raise before the flop and a bet after it added up to one of the strongest hands you could hold, whoever made them. That is the right read of somebody who only bets when they have it. It is exactly the wrong read of somebody who bets every time, and the bots could not tell the two apart. They had no memory of who they were playing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The bots remember you.&lt;/strong&gt; &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/ai/memory.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/ai/memory.ts&lt;/code&gt;&lt;/a&gt; counts, for every player at the table, how often they raise before the flop, how often they bet after it, and how often they fold when bet into. Everybody starts out as a typical player, and a few orbits move the count where one hand cannot. A bet from somebody who bets everything says less, so the bots call it down and raise it back. Against somebody who folds a lot, they bluff more.&lt;/p&gt;

&lt;p&gt;The same flop bet now gets folded to 62% of the time from a stranger, and 27% of the time from a player the table has watched bet the pot at every chance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A bet is read by its size against this street’s pot&lt;/strong&gt; , with a smaller weight for earlier streets, instead of counting every chip in the hand as proof. That is &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/ai/policy.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/ai/policy.ts&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short stacks play the chart.&lt;/strong&gt; At fifteen big blinds or fewer, first in or facing one shove, the strong bots go all-in or fold from the same solved chart Pip’s shove-or-fold drill teaches (&lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/ai/pushFold.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/ai/pushFold.ts&lt;/code&gt;&lt;/a&gt;). The blinds here climb every few hands, so a lot of a tournament is played that short. The Main Event plays off the chart every time. Lower tables do it less often.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bet sizes stop giving the hand away&lt;/strong&gt; from the middle of the ladder up. A bluff there is sized more like a bet for value, and at the top they look the same. The lower tables keep the tell on purpose. A table you can read is where you learn to read.&lt;/p&gt;

&lt;p&gt;With all of that in, the same script won 83 of 600 at the Main Event, down from 117.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then they learned the story
&lt;/h2&gt;

&lt;p&gt;A second change went in the same afternoon. The bots now read the hand as a sequence, not a pile of chips: who raised before the flop, who check-raised, who has led every street. The raiser bets the flop more often. A big hand sometimes checks to the raiser so it can raise later. A seat that has bet every street can finish the bluff on the river. And the table’s count of how often you fold now changes how often it bluffs you.&lt;/p&gt;

&lt;p&gt;In 300 tournaments against that table, where a fair share is 50, the c-bet script won 44. The one that bets every street it is checked to won 24.&lt;/p&gt;

&lt;h2&gt;
  
  
  How sure we are
&lt;/h2&gt;

&lt;p&gt;Six hundred tournaments is not many. A player no better than the table wins 117 or more about one time in 27 by luck alone, so 117 on its own would not have convinced us. The fold rate did. Seven folds in ten against a break-even of four in ten is arithmetic, and a strategy that profits on most flops was always going to show up in the results.&lt;/p&gt;

&lt;p&gt;The 44 in 300 says less. A player exactly as good as the table lands there or lower about one time in five, so it says the c-bet stopped winning big, and nothing finer than that. The 24 is a different matter: luck gets that low about once in a hundred thousand tries.&lt;/p&gt;

&lt;p&gt;To make 600 tournaments finish, those runs held each bot to 300 simulated hands per decision. The real Main Event thinks through 1,800. And these are scripts, not people. A script does not get bored, change gear or notice that the table has started calling. The real test is a person sitting back down at the Main Event, and that one is open to anybody who gets there.&lt;/p&gt;

&lt;h2&gt;
  
  
  For the human at the table
&lt;/h2&gt;

&lt;p&gt;Betting all the time works against opponents who do not adjust. Against a table that is watching, a bet that never means anything stops buying folds and starts getting called. The Main Event watches now.&lt;/p&gt;

&lt;p&gt;The ladder, the Rail, the Daily and the freeroll stay free. The shove-or-fold drill the bots learned from is in the &lt;a href="https://playpip.io/membership?for=drills&amp;amp;drill=shove-or-fold&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>development</category>
      <category>programming</category>
      <category>software</category>
    </item>
    <item>
      <title>Why a flush beats a full house in Short Deck</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/why-a-flush-beats-a-full-house-in-short-deck-3cl8</link>
      <guid>https://dev.to/playpipio/why-a-flush-beats-a-full-house-in-short-deck-3cl8</guid>
      <description>&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;Short Deck is Hold’em with the deuces, threes, fours and fives taken out. Thirty-six cards are left, and two rules come with them: a flush beats a full house, and the ace can play low under the six, so A-6-7-8-9 is a straight.&lt;/p&gt;

&lt;p&gt;The first one sounds like a house rule somebody lost an argument over. It is arithmetic. Poker ranks hands by how hard they are to make, and on a short deck the flush is the harder one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counting them
&lt;/h2&gt;

&lt;p&gt;A full deck deals 2,598,960 different five-card hands. The standard counts are 5,108 flushes and 3,744 full houses, so the flush is the more common hand and ranks below.&lt;/p&gt;

&lt;p&gt;A short deck deals 376,992. Of those, 480 are flushes and 1,728 are full houses. Same question, other answer.&lt;/p&gt;

&lt;p&gt;We did not look these up. &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/shortDeckCounts.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/shortDeckCounts.test.ts&lt;/code&gt;&lt;/a&gt; deals every one of the 376,992 through the evaluator that settles Pip’s Short Deck pots, and fails if a count moves. It also checks that on five cards, from a pair upwards, every hand in the order is rarer than the one below it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the deck does it
&lt;/h2&gt;

&lt;p&gt;A flush needs five cards of one suit. A suit used to have thirteen cards and now has nine, so the ways to pick five from it fall from 1,287 to 126. A full house needs ranks, and every rank left in the deck still has all four of its cards. Stripping the deck costs the full house some company. It costs the flush most of its options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seven cards say the same
&lt;/h2&gt;

&lt;p&gt;In Hold’em you play the best five of seven, so we counted those too: all 8,347,680 seven-card hands on a short deck. 633,024 end as a full house and 175,560 as a flush. The flush is still the rarer hand.&lt;/p&gt;

&lt;p&gt;The same count found 233,100 that end as nothing at all. On a short deck, seven cards make a full house more often than they make high card. Two pair turns up more often than one pair. It is not a game for anybody who enjoys folding.&lt;/p&gt;

&lt;p&gt;That run takes minutes rather than a second, too long for the test suite, so the seven-card counts are not pinned by a test the way the five-card ones are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where rarity stops
&lt;/h2&gt;

&lt;p&gt;The order does not follow rarity all the way. It stops at the bottom: on five short-deck cards, nothing at all (122,400 hands) is rarer than a pair (193,536), and nobody has proposed ranking nothing above a pair.&lt;/p&gt;

&lt;p&gt;It wobbles in the middle too. On five cards a straight is rarer than three of a kind, 6,120 to 16,128. On seven it is not: 1,169,940 straights against 607,200 sets of trips. In Pip the straight still wins.&lt;/p&gt;

&lt;p&gt;Some rooms swap the two for exactly that reason. Pip plays the Triton rules, which is what most players mean by Short Deck: flush over full house, the ace low under the six, and everything else in the usual order. &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/shortDeck.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/shortDeck.ts&lt;/code&gt;&lt;/a&gt; says which rule set it picked, because choosing quietly between two real rule sets is how a showdown ships wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ace plays low
&lt;/h2&gt;

&lt;p&gt;With the deuce through five gone, the lowest straight is A-6-7-8-9, the ace standing in below the six. It is a nine-high straight, not an ace-high one, and the difference is a pot: scored as ace high it would beat the ten-high straight it loses to.&lt;/p&gt;

&lt;p&gt;The hand library we use for Hold’em reads A-6-7-8-9 as ace high and nothing else, and puts a full house over a flush, without mentioning either. It is the same library we have &lt;a href="https://playpip.io/blog/pokersolver-undocumented" rel="noopener noreferrer"&gt;written about before&lt;/a&gt;. So Short Deck has its own evaluator, and &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/shortDeck.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/shortDeck.test.ts&lt;/code&gt;&lt;/a&gt; holds both rules, including a check that a short-deck hand is never handed to the library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;Short Deck is one of the side tables in the &lt;a href="https://playpip.io/membership?for=shortdeck&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;, at three stakes. The ladder, the Rail, the Daily and the freeroll stay free. So did the arithmetic.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Omaha’s exactly-two rule, in five hands</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/omahas-exactly-two-rule-in-five-hands-3cgl</link>
      <guid>https://dev.to/playpipio/omahas-exactly-two-rule-in-five-hands-3cgl</guid>
      <description>&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;In Pot-Limit Omaha you are dealt four cards instead of two. At showdown your hand is exactly two of those four and exactly three of the five on the board. Not one of yours and four of the board. Not three and two. Two and three, every time.&lt;/p&gt;

&lt;p&gt;That is the whole difference at showdown, and it is enough to make most Hold’em instincts wrong. Below are five hands, each read twice: once the Hold’em way, best five of seven, and once the Omaha way. Every answer here came out of the evaluator that settles Pip’s Omaha pots, not out of our heads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four hearts is not a flush
&lt;/h2&gt;

&lt;p&gt;You hold the ace, king, queen and jack of hearts. The board is 2♥ 7♣ 8♦ 9♠ 10♠.&lt;/p&gt;

&lt;p&gt;In Hold’em that is an ace-high flush. In Omaha it is a queen-high straight. Only two of your hearts may play, and a flush needs three more from the board, which has one. The straight is your queen and jack with the 10, 9 and 8.&lt;/p&gt;

&lt;h2&gt;
  
  
  Neither is one
&lt;/h2&gt;

&lt;p&gt;The other way round. The board is A♥ 9♥ 6♥ 3♥ K♣ and you hold Q♥ 7♠ 4♦ 2♣.&lt;/p&gt;

&lt;p&gt;In Hold’em the queen of hearts makes a flush. In Omaha you have ace high and nothing else, because you must use two of your cards and only one of them is a heart. Four to a flush on the board plus one in your hand is the most expensive nothing in the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  The board is not your hand
&lt;/h2&gt;

&lt;p&gt;The board is 9♣ 9♦ 9♥ 2♣ 2♦: a full house all by itself. You hold A♠ K♦ Q♥ J♠.&lt;/p&gt;

&lt;p&gt;In Hold’em everybody plays the board and splits it. In Omaha you have three nines with an ace and a king, since only three board cards play and two of yours must. Anybody with a pair among their four has at least the full house you do not, and the last nine makes four of a kind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sometimes the rule gives
&lt;/h2&gt;

&lt;p&gt;The board is 9♣ 9♦ 9♥ 5♣ 2♦ and you hold A♠ A♦ 7♣ 8♦. Nines full of aces, both ways. A pair in your hand is exactly how you use a board with trips on it, and the rule takes nothing off you here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two pair is one pair
&lt;/h2&gt;

&lt;p&gt;You hold K♣ K♦ 5♠ 5♥. The board is 6♣ 7♦ 8♥ 9♠ Q♣.&lt;/p&gt;

&lt;p&gt;In Hold’em one of your fives finishes a straight. In Omaha that straight would be one of your cards and four of the board’s, which is not allowed. You play the kings with the queen, nine and eight: a pair of kings, on a board where anybody holding a ten and a jack has a straight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sixty hands at every showdown
&lt;/h2&gt;

&lt;p&gt;Two of four cards can be chosen six ways. Three of five can be chosen ten ways. So every Omaha player at a showdown has sixty legal hands, and &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/handEval.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/handEval.ts&lt;/code&gt;&lt;/a&gt; builds all sixty and keeps the best. It does not reason about which two cards ought to play, because that reasoning is where Omaha evaluators go wrong, and sixty five-card hands is not much work.&lt;/p&gt;

&lt;p&gt;We could have left the reading to the hand library we use. We have &lt;a href="https://playpip.io/blog/pokersolver-undocumented" rel="noopener noreferrer"&gt;written before&lt;/a&gt; about what that library does without telling you, so the rule is ours, where a test can hold it. &lt;a href="https://github.com/playpip/pip-web/blob/main/tests/omaha.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;tests/omaha.test.ts&lt;/code&gt;&lt;/a&gt; deals sixty random hands and checks that each best five is two from the hand and three from the board.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pot limit
&lt;/h2&gt;

&lt;p&gt;The other half of the name. The most you can raise is the size of the pot after you call. At The Big Pot the blinds start at 25 and 50 and everyone sits with 10,000. First to act before the flop, there are 75 chips in the middle. Calling 50 makes it 125, so you may raise by 125 more: 175 in all. At a no-limit Hold’em table the same seat could put in all 10,000.&lt;/p&gt;

&lt;p&gt;The sum is in &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/poker/engine.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/poker/engine.ts&lt;/code&gt;&lt;/a&gt;, written out, because the usual mistake is to raise by the pot before your call and come up short.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is
&lt;/h2&gt;

&lt;p&gt;Pot-Limit Omaha is The Big Pot, one of the side tables in the &lt;a href="https://playpip.io/membership?for=omaha&amp;amp;from=blog" rel="noopener noreferrer"&gt;membership&lt;/a&gt;. The ladder, the Rail, the Daily and the freeroll stay free. The rule was always free to read, and now you have.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>gamedev</category>
      <category>software</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>What Google and Apple tell us when you sign in</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Sun, 04 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/what-google-and-apple-tell-us-when-you-sign-in-463k</link>
      <guid>https://dev.to/playpipio/what-google-and-apple-tell-us-when-you-sign-in-463k</guid>
      <description>&lt;h2&gt;
  
  
  Two new buttons
&lt;/h2&gt;

&lt;p&gt;The account dialog now offers Continue with Google and Continue with Apple, above the email and password it already had. You press one, go to Google or Apple for a moment, and come back to the page you left, signed in, with your Roll syncing.&lt;/p&gt;

&lt;p&gt;An account is still optional. This only changes how long it takes to make one if you want one, which used to be the time it takes to think of a password.&lt;/p&gt;

&lt;h2&gt;
  
  
  What they hand us
&lt;/h2&gt;

&lt;p&gt;A button that says Continue with Google is also a small data transfer, and the button does not mention it. So here it is, in the same words as &lt;a href="https://github.com/playpip/pip-web/blob/main/src/app/privacy/page.tsx" rel="noopener noreferrer"&gt;the privacy page&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Both send&lt;/strong&gt; your email address and an id for your account with them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google also sends&lt;/strong&gt; the name and picture on your Google account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple sends your name&lt;/strong&gt; the first time, and lets you hide your email, in which case we only ever see a relay address Apple makes up for us.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Supabase keeps those with the account record. Pip never shows or uses them: nothing in the app reads the name or the picture, and deleting the account deletes them. We do not need them either. They come with the sign-in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two details we cared about more than you will
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A button only appears once it works.&lt;/strong&gt; A provider that is not switched on behind the scenes sends whoever presses it to a page of raw JSON on someone else’s domain. So the build lists the providers it offers, and a button is not drawn until its provider is on (&lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/sync/client.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/sync/client.ts&lt;/code&gt;&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An account made this way has no password&lt;/strong&gt; , so it does not offer to change one. It says Set a password instead, and setting one lets you sign in with your email as well (&lt;a href="https://github.com/playpip/pip-web/blob/main/src/store/sync.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/store/sync.ts&lt;/code&gt;&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is interesting. Both are the sort of thing that, done the other way, ends up as a support email.&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>privacy</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Pot odds when you can’t cover the bet</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Fri, 02 Oct 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/pot-odds-when-you-cant-cover-the-bet-35h1</link>
      <guid>https://dev.to/playpipio/pot-odds-when-you-cant-cover-the-bet-35h1</guid>
      <description>&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;There are 500 chips in the middle. Someone bets 1000. You have 300 left. The usual pot odds sum says you pay 1000 to win 1500, so you need a quarter of the pot. That sum is wrong twice over, because you are not paying 1000 and you are not playing for 1500.&lt;/p&gt;

&lt;p&gt;Our session review made both mistakes, and the report and the read you get after a hand made the second one. All three are fixed. This is the right sum, and what the wrong one told people.&lt;/p&gt;

&lt;h2&gt;
  
  
  You call for what you have
&lt;/h2&gt;

&lt;p&gt;A bet bigger than your stack does not cost you the bet. It costs you your stack. Calling puts your 300 in and you are all in, which is what the engine charges and what the &lt;em&gt;Call&lt;/em&gt; button already said.&lt;/p&gt;

&lt;p&gt;The other 700 of their bet is not yours to win either. Nobody matched it. With one opponent it goes straight back to them; with more, it starts a side pot you have no claim on. What you are playing for is the 500 that was there, plus your 300, plus the 300 of theirs you covered: 1100.&lt;/p&gt;

&lt;p&gt;Pot odds are what you put in over the pot you could take, your call included: 300 out of 1100, about 27%. The wrong sum, 300 out of the full 1800, says about 17%. A hand with 20% to win looks like a call on the wrong sum and loses 80 chips on the right one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the review said
&lt;/h2&gt;

&lt;p&gt;The review steps back through your session and grades every move at the table, yours and the regulars’, against the cards everyone actually held. For anybody but you it worked out the price from the chips in front of each seat, and it priced a short stack at the full bet, against the full pot.&lt;/p&gt;

&lt;p&gt;Take the same spot, blinds at 10 and 20, with the short stack holding 35% against the bettor. The wrong sum takes 35% of a 2500 pot and charges 1000 for it: minus 125. Folding saved 125 chips, so the review marked the fold as good. The right sum takes 35% of 1100 and charges 300: plus 85. The fold gave up 85 chips, about four big blinds. The review told you the opposite of what happened, with a number attached, which is the worst way to be wrong.&lt;/p&gt;

&lt;p&gt;The fix is in &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/review/moveGrade.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/review/moveGrade.ts&lt;/code&gt;&lt;/a&gt;: call for the smaller of the bet and the stack, and take what nobody could match out of the pot. A test pins the spot above at minus 85.&lt;/p&gt;

&lt;p&gt;The report and the read after a hand work from somewhere else: a note the game makes when you act. That note charged you the right 300 and still counted the whole pot, so both judged your short calls on the 17% sum. &lt;a href="https://github.com/playpip/pip-web/blob/main/src/lib/coach.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/lib/coach.ts&lt;/code&gt;&lt;/a&gt; now leaves the unmatched chips out. Sessions saved before the fix keep the old note, so the report still grades those spots the old way.&lt;/p&gt;

&lt;h2&gt;
  
  
  While we were in there
&lt;/h2&gt;

&lt;p&gt;The report that comes with the review had a smaller habit of the same kind. Under &lt;em&gt;You pay off too often at the end&lt;/em&gt;, its &lt;em&gt;See the hands&lt;/em&gt; list could show a hand you folded, which is a strange way to prove you pay off. Only calls go there now, and folds already saved on your profile are left out when the list is drawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why short stacks
&lt;/h2&gt;

&lt;p&gt;Every venue on the ladder is a tournament, and tournaments end in short stacks. A short stack’s whole hand is often one call. If the number on that call is wrong, there is no second decision to make up for it.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Deal me in dealt you a menu</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Wed, 30 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/deal-me-in-dealt-you-a-menu-47eh</link>
      <guid>https://dev.to/playpipio/deal-me-in-dealt-you-a-menu-47eh</guid>
      <description>&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;When you make a player, the next screen offers a short tour or a button that says &lt;em&gt;Deal me in&lt;/em&gt;. Until 30 September that button took you to the lobby, which is a lot of things to choose between and none of them a hand of cards. In September, 217 people made a player and 149 of them played a hand within the hour. The other 68 made a character, picked a face for it, and did not play a hand that hour.&lt;/p&gt;

&lt;p&gt;Now the button deals you in. It seemed the least we could do, given the name.&lt;/p&gt;

&lt;h2&gt;
  
  
  It wasn’t the tour
&lt;/h2&gt;

&lt;p&gt;The obvious suspect was the tour, since it sits between making a player and playing. It was innocent. Of the 77 who took it, 52 went on to play a hand. Of the 140 who skipped it, 97 did. Two in three either way, which says people were leaving at the page both routes ended on, and that page was the lobby.&lt;/p&gt;

&lt;p&gt;The lobby is fine for someone who knows what the Rail is. For someone who has been a poker player for forty seconds, it is a menu at a restaurant they have not decided to eat at.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Deal me in&lt;/em&gt;, the tour’s &lt;em&gt;Take a seat&lt;/em&gt;, and &lt;em&gt;Skip&lt;/em&gt; on a tour you started from that screen all go straight to a table now. Which table is the same pick the lobby’s &lt;em&gt;Next up&lt;/em&gt; card makes, so the two can’t disagree; for a new player it is Friends’ Garage. That pick lives in &lt;a href="https://github.com/playpip/pip-web/blob/main/src/components/onboarding/firstSeat.ts" rel="noopener noreferrer"&gt;&lt;code&gt;src/components/onboarding/firstSeat.ts&lt;/code&gt;&lt;/a&gt;, which is short. If you haven’t made a player yet, you still go to the page that makes one.&lt;/p&gt;

&lt;p&gt;The lobby is still there. You just meet it after you’ve seen a card.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we don’t know yet
&lt;/h2&gt;

&lt;p&gt;Whether it worked. The numbers above come from our analytics, which count browsers rather than people, over one month. We will read the same step again at the end of October. If it hasn’t moved, the lobby wasn’t the problem either, and we will say so here.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>product</category>
    </item>
    <item>
      <title>Pip has a membership now</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Tue, 29 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/pip-has-a-membership-now-4l01</link>
      <guid>https://dev.to/playpipio/pip-has-a-membership-now-4l01</guid>
      <description>&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;p&gt;Pip has a membership. £5.99 a month or £49 a year. We waited to write this until a real card had gone through it and come out the other side.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it buys
&lt;/h2&gt;

&lt;p&gt;The side tables, Pot-Limit Omaha, Short Deck, Omaha Hi-Lo, Five-Card Draw, and blackjack, for some reason. Levels 2 to 5 of Lessons with Webb, every drill, Session review, and the members’ shelf. The full list is on &lt;a href="https://playpip.io/membership" rel="noopener noreferrer"&gt;/membership&lt;/a&gt;, which is built from the same file the game reads, so it cannot list something that is not built.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn’t
&lt;/h2&gt;

&lt;p&gt;The ladder, the Rail, the Daily and the freeroll are free forever. Level 1, every written guide, the odds calculator and the per-hand read are free too. Nothing you can buy changes a hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  On your statement
&lt;/h2&gt;

&lt;p&gt;It is sold by Ava Technologies Global Ltd, so your statement says &lt;code&gt;AVA TECH* PIP&lt;/code&gt;. To cancel: Settings, Membership, Manage. We don’t ask why.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The mock-ups on your landing page are untested claims</title>
      <dc:creator>Play Pip</dc:creator>
      <pubDate>Thu, 17 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/playpipio/the-mock-ups-on-your-landing-page-are-untested-claims-1bde</link>
      <guid>https://dev.to/playpipio/the-mock-ups-on-your-landing-page-are-untested-claims-1bde</guid>
      <description>&lt;h2&gt;
  
  
  Four cards, and a comment at the top of the file
&lt;/h2&gt;

&lt;p&gt;Our home page has four feature cards. Each one carries a small picture of something the game produces: the line you copy after playing the Daily, a shared hand’s link, the win percentage that sits at the table, an avatar with a fan of card backs. They are not images. They are components, laid out in the same design system as the real thing and rendered live on the page, which is why they look right.&lt;/p&gt;

&lt;p&gt;The file they live in opens with a comment saying that nothing on the page is a mock-up: what you see here is what you get at the table. That sentence was written when it was true. It stayed in the file for four months, during which three of the four cards drifted away from the product, and the test suite was green every day of it.&lt;/p&gt;

&lt;p&gt;The one that did not drift is the difference. It maps over the same config the game reads, so there was nothing in it to get wrong. The other three were typed out by hand next to the code that produces the real version.&lt;/p&gt;

&lt;h2&gt;
  
  
  One: the share line with the share missing
&lt;/h2&gt;

&lt;p&gt;The Daily card sells the loop. Everyone plays the identical shuffle, so the result line is worth pasting somewhere, and the app appends &lt;code&gt;playpip.io/daily&lt;/code&gt; to it so whoever reads it can go and play the same deal.&lt;/p&gt;

&lt;p&gt;The card drew that line by hand, from before the address existed. So the card whose entire argument is the share loop displayed the version of the line with the loop cut off, for the month after we shipped it. Not a wrong number. The missing part was the part that made it a mechanism.&lt;/p&gt;

&lt;p&gt;The fix is one line: call &lt;code&gt;dailyShareText&lt;/code&gt;, the function the app shares with, with fixed arguments. The card now cannot show a line the app would not produce, because it is not drawing a line, it is asking for one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two: a link that looked like somebody else's database
&lt;/h2&gt;

&lt;p&gt;The second card says a shared hand needs no server and no account, because the whole hand is folded into the URL fragment. It illustrated that with &lt;code&gt;playpip.io/hand#kQyJ3v…&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Six characters and an ellipsis. That is a perfectly normal-looking link, which is the problem: it is what a link looks like when it points at a row in somebody’s database. Short opaque token, server on the other end, gone when the company folds. The picture contradicted the claim it was there to support, and it did it in the visual grammar everyone already reads fluently.&lt;/p&gt;

&lt;p&gt;A real one is not like that. We encode the hand as JSON and base64url it, so the length is the hand: every action, every board card, every name, every reveal. The hand now on the card is a six-handed pot that reaches showdown, and it is 566 characters of URL.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;the card, at build time&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;playpip.io/hand#eyJ2IjoxLCJuIjo0MiwiYiI6… (566 characters)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;566 characters is not elegant and we are not going to pretend otherwise. It is also the entire point. You can read the hand out of the link with a base64 decoder and no permission from us, and nothing we do later takes a hand away from someone who has the URL. Both numbers in this paragraph are the length of the string in the block above it, because the page computes them at build time. Anything else would be a fourth hand-typed claim in a post about hand-typed claims.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three: a phrase the game has never said
&lt;/h2&gt;

&lt;p&gt;The third card shows the ambient equity read: how often you win this hand from here, sitting quietly at the edge of the table. The hand-typed version said &lt;code&gt;Top pair, good kicker&lt;/code&gt; over &lt;code&gt;72%&lt;/code&gt;, with &lt;code&gt;ahead of 4 in 5 hands&lt;/code&gt; underneath.&lt;/p&gt;

&lt;p&gt;Three problems, and only the first is the kind you would call a bug.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The game has never emitted that label.&lt;/strong&gt; The readout calls &lt;code&gt;evaluateHand(hole, community).name&lt;/code&gt; and prints whatever comes back, which for ace-king on an ace-high flop is the word &lt;code&gt;Pair&lt;/code&gt;. Flat, and a bit deflating, and what the product says. Our evaluator also calls a royal flush a &lt;a href="https://playpip.io/blog/pokersolver-undocumented" rel="noopener noreferrer"&gt;Straight Flush&lt;/a&gt;, so this is not the first time its naming has surprised us.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;72% and four in five are two answers to one question.&lt;/strong&gt; Four in five is 80%. Whichever was right, the box printed a number and then restated it as a different number, eight points away, in the next line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neither figure came from a hand.&lt;/strong&gt; There was no spot behind the card, so there was nothing either number could be checked against. A percentage nobody can reproduce is decoration in the shape of evidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The card now names its spot: ace-king on ace-nine-four, three opponents still in. The label is what &lt;code&gt;evaluateHand&lt;/code&gt; returns for it. The percentage is 70%, which is where the equity lands (70.20% over 20 runs of 20,000 hands, standard deviation 0.39). The sentence restating it in words is gone, because that sentence was a second claim with nothing under it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the suite stayed green
&lt;/h2&gt;

&lt;p&gt;We have a lot of tests about claims. One walks every page looking for absolutes about money that a paid tier would falsify, because we shipped two of those and served them for sixteen days. One fails if the list of paid drills drifts from the code. We are, if anything, fussy about this.&lt;/p&gt;

&lt;p&gt;Two of them walk this exact file. They read every line of the landing page on every run, and they did it while all three cards were wrong, because what they are looking for is a phrase. A banned form of words about money. A sentence that contradicts the roadmap. Miss the phrase and you catch the claim.&lt;/p&gt;

&lt;p&gt;A mock is not a phrase. Nobody was ever going to add &lt;code&gt;Top pair, good kicker&lt;/code&gt; to a list of sentences we must not write, because until you go and read &lt;code&gt;evaluateHand&lt;/code&gt; it is not a false sentence, it is a plausible label. The same goes for a short URL: no string in it is wrong. What is wrong is the relationship between it and a function somewhere else, and grep cannot see a relationship.&lt;/p&gt;

&lt;p&gt;That is the generalisable bit, and we do not think it is specific to us. If your marketing page draws your product’s output rather than screenshotting it, you have written claims that no amount of looking for bad sentences will find, in a file that survives every rename and refactor because nothing imports it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule we ended up with
&lt;/h2&gt;

&lt;p&gt;Two ways to draw your own output, and one of them has to be true by construction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Call the function.&lt;/strong&gt; If something real produces the string, the card asks it for the string with fixed arguments. The Daily line and the hand link both do this now. This is the better option and it is usually available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Or make a test recompute it.&lt;/strong&gt; Sometimes calling the function is a bad trade: the equity read would drag the hand evaluator and a Monte-Carlo run into the bundle for one card. So the inputs and the expected numbers sit in a config file, the page renders the constants, and a test runs the real thing against them and fails on a gap of more than a point.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tests are in &lt;code&gt;tests/landingMocks.test.ts&lt;/code&gt;. One of them greps the landing page for a typed-out hand link and fails if it finds one, which caught its own author within a minute: we had quoted the old six-character link in a code comment explaining why it was wrong.&lt;/p&gt;

&lt;p&gt;There is a fourth card we have not mentioned. It draws a face and three card backs by mapping over the cast and the deck config, which is the same config the game maps over. It has been correct since the day it was written, and nobody has ever had to think about it. That is the whole argument.&lt;/p&gt;

</description>
      <category>design</category>
      <category>frontend</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
