With a number of new challenges springing up it’s looking like that early October completion date for CypherPoker might be a bit optimistic. This is especially true when trying to anticipate challenges with other people’s code (i.e. Ethereum) and it seems that with the previous step forward I’ve had to take a few steps back.
You may recall that in the last update I incorporated the Ethereum client (Geth) along with a basic console interface. The idea here was to provide naked access to all of the core Etheum client functionality: creating accounts, deploying smart contracts, gathering network/transaction information, mining, etc. I didn’t expect this to see much action from casual users since CypherPoker will be performing automated exchanges with the client in the background, but I was expecting to be able to use it during development to deploy smart contracts to the Ethereum blockchain in an easy way.
While I use Browser Solidity to write and test smart contract code I find that it’s somewhat flaky with more complex code and incomplete in a few ways*. It’s certainly not my intention to disparage the author as it’s still a great product and these issues can all be addressed with future updates but it does impose limits in the meantime. To get around them I would run Geth from the command line and paste the compile Web3 deploy output from Browser Solidity into the window but this operation took f…o…r…e…v…e…r, especially with lengthier contracts (1 KB+). It would become exceedingly annoying when, having waited a minute and a half for the paste operation to complete, I realized there was an error in the code and would have to start all over again.
With the shiny new interface built into CypherPoker it looked like I would have the best of all worlds – a nice editor with Browser Solidity, a reliable testing ground with Geth, and a fast way to get data from one to the other.
Unfortunately, I quickly discovered that larger Web3 deploy data was being broken up into discrete chunks in the process and this would cause Geth to spit out multiple errors. It’s as though carriage returns+line feeds were being inserted at regularly inconvenient locations throughout the code. I tried a variety of parsing methods – stripping out CR/LFs and tab characters, breaking up the deployment data into interface and data sections, creating a buffer to feed the data to Geth in chunks, etc. – but it didn’t help. I’m still not sure why this happens; perhaps it has something to do with a buffer limit on the STANDARD INPUT pipe? Is this why the command line paste operation is so slow?
I had to return to the drawing board to come up with a new solution, lest I was willing to be extremely patient and test my smart contract code the old way.
I settled on incorporating the standalone Solidity compiler (solc) in order to compile the contract source code which I can then transform and deploy to the blockchain via the RPC interface. This allows for much more freedom, from simple things like specifying the gas amount to more complex procedures like linking dependent contracts. This second point is especially important since much of the CypherPoker smart contract infrastructure consists of libraries, reusable code that is typically deployed only once and then referenced by new contracts. This is accomplished through the aforementioned linking process in which the blockchain addresses of deployed libraries are inserted, or linked, into the compiled code of new contracts. The standalone Solidity compiler does this in a second step (after compiling), since the addresses of libraries can’t be known until they’ve actually been deployed. Since I have control of the deployment process along with the compiler, however, I’m able to run the compiler just once and then link-deploy the whole series of smart contracts in (what appears to be) a single step. More importantly, it’s relatively fast.
I’ve found this handy (and generic) enough to consider splitting off this functionality off into its own app but for now there are bigger fish to fry.
With this problem out of the way I was able to begin focusing on the actual smart contracts themselves.
Much has happened to the Solidity language since I produced the first proof-of-concept smart contracts for CypherPoker and the source code simply won’t compile as-is anymore. There was a rather large change to the way that libraries are written and since CypherPoker’s smart contracts are mostly libraries it meant a rather large re-write of the source code.
The biggest of these libraries is the Poker Hand Analyzer (soon to be renamed from pha.sol) which, on top of having the most functionality, was one of the few that was written as a standard contract rather than a library because of its reliance on specific memory structures.
As the name suggests, this library is responsible for analyzing a series of provided cards and producing a score based on the poker hand combination it finds. The higher the score the more valuable a hand is (i.e. the highest-scoring hand wins). The numeric score produced by the Analyzer is in a range that makes it very easy to recognize what kind of a hand the player has:
800,000,000 to 899,999,999 = Straight Flush / Royal Flush
700,000,000 to 799,999,999 = Four of a Kind
600,000,000 to 699,999,999 = Full House
500,000,000 to 599,999,999 = Flush
400,000,000 to 499,999,999 = Straight
300,000,000 to 399,999,999 = Three of a Kind
200,000,000 to 299,999,999 = Two Pairs
100,000,000 to 199,999,999 = One Pair
1 to 99,999,999= High Card
The initial version of the Analyzer took 7 cards and returned the highest score of any 5-card permutation. I realized, however, that the Analyzer won’t be invoked unless the results of a game are challenged so there really isn’t a need for all 7 permutations to be analyzed. Instead, along with providing sufficient funds to cover the results of a losing challenge a player will supply their 5 best cards to the contract. The implication here is that it will be up to the game client to analyze all of the possible permutations instead of paying the contract to do the work. Since each player’s cards are proven and irrevocably stored in the contract, providing a less-than-highest combination for scoring will only work against the player.
This approach will save a significant amount of gas and allow me to cut back on some of the library’s functionality.
Now that the integration between CypherPoker and Ethereum is sufficiently advanced there’s going to need to be some way for players to specify their wallet address and password. There’s also a growing list of options and features that will require a user interface so I’ve been putting together some wireframes for the CypherPoker v2.0 UI overhaul.
I want to caution that these are wireframes which are intended primarily as guides for layout. While I make use of some common symbols these are intended mostly as placeholders, not as final user interface elements.
Since plenty of time has been spent ensuring that the CypherPoker code is seamlessly compatible across a wide variety of environments and devices, one of the first things I produced was a guide with the most common display dimensions within which the user interface may exist. Subsequent design elements are aligned to these dimensions.
Using the smallest dimensions (800 by 600 pixels), I considered how I might be able to dynamically fit all of the necessary, and optional, elements while maintaining a singular design. It quickly became obvious that I wouldn’t be able to fit in all of the various features into the smallest dimensions but I also didn’t want all of the extra space on larger displays to go to waste so I came up with a sliding and expanding panel system.
The main game area will rest in the upper middle of the display and will be bordered by three dynamic panels: one below and one on each side.
The initial layout pictured above will accommodate the smallest (800 by 600) display area. The chevron tabs closest to the cards will be visible in the main game area and will be used to slide the corresponding panels into view. For example, the clicking on the top chevron tab of the bottom panel will cause that panel to slide into view from the bottom. Similarly, the right and left chevron tabs (pictured beside the Ace and Five), will slide their corresponding tabs into the game area.
The other chevron tabs on the panels will cause the content within the panel to be scrolled so that more than one page of options can be displayed. In the bottom panel additional content will scroll horizontally while in the side panels additional content will scroll vertically. If there are no additional pages in the panel the scrolling chevrons won’t appear and there will also be some sort of close button (not pictured), in order to retract the panels back into place.
The panel design lends itself well to larger displays. When both side and bottom panels can be shown in their entirety (without having to slide them in), they can be expanded to show as many options as will fit.
If the bottom panel contains the predominant features it can span the width of the display…
…and if the side panels contain the most-used features they can be expanded while the bottom panel will shrink horizontally to fit…
Depending on the player’s preferences the panels will remain at their set sizes or can resize themselves according to context. For example, upon clicking/tapping on the bottom panel in the above diagram it (the bottom panel), would expand horizontally while the side panels would shrink vertically. Any options that don’t fit into their respective panels’ areas can again be scrolled into view using the scrolling chevrons.
Above the main game area there will appear a sliding Players bar displaying each player’s status, icon, and some other useful information. To accommodate any potential number of players this bar will scroll horizontally. I think it’d make sense for the currently active player to appear in one of the side panels along with extended information. Because CypherPoker also supports live video chat, using a larger icon/video area here would make sense.
While the final layout of content within panels is yet to be determined the plan is for primarily horizontal items to appear in the bottom panel and primarily vertical or smaller elements to appear in the side panels.
For example, the player’s Ethereum/Bitcoin address fields will most likely appear in the bottom panel while toggle controls (checkboxes/radio buttons), would appear in side panels. Context will also be important in deciding where various controls go – it wouldn’t make much sense to put a network-type selection pulldown in one panel while putting the network sub-options in another panel.
Finally, there will be overlay interface elements such as password entry fields or information dialogs that will appear temporarily on top of all other content. Usually these dialogs will be blocking in order to prevent interactions with user interface elements underneath. For example, when further actions can’t be completed without an account password it makes sense for the dialog to prevent any other interactions until the password is supplied.
Now that CypherPoker v2.0 is in the homestretch I would very much appreciate your input. Even if there are features or design elements that I can’t implement for version 2.0 it may be worth it to add them to the to-do list so I would encourage you to get in touch.
As I mentioned at the beginning, an early October completion date seems highly unlikely at this point but mid-October still seems to be a possibility. It’s difficult to predict the roadblocks I’ll hit on the way but without a doubt each day gets the project a little closer so keep watching this space for updates!