# What it is ***Note:** Since the application is still in development, it is common for components to be unavailable, unresponsive, or outright unusable. If you're able to, please [submit a message](/contact) with the text of the page with Copy/Paste (Ctrl+A, Ctrl+C, Ctrl+V) and any additional information.* **cl-deck-builder2** is really three things: - [Inventory Management](#inventory) - [Deck Builder](#builder) - [Unifying User Interface](#ui) This application merges these things into a web interface where you can create, modify, and update decks, pricing, and inventory data. It is a web app written in [Common Lisp](https://lisp-lang.org/learn/first-steps) using [Caveman2](https://github.com/fukamachi/caveman). ## Inventory Management The inventory manager is located here: [/cards](/cards). **cl-deck-builder2** aims to suppliment Crystal Commerce Product Manager tools. The original intent was to allow CSV upload of Product Names from Crystal Commerce. This proved to be unnecessary, as YGOProDeck has all of the information in the `card_sets` arrays for each card. The Inventory editor has been superseded by the YGOProDeck editor. The CSV components and all of the Crystal Commerce code is in maintenance mode, and due to be removed, as there is no way to access or update this information currently. ### How To Use It Currently the following features are supported: - Partial List of Inventory Items: [Inventory List](/cards) - Clicking on the card image will take you to the Inventory for that card - Each Card has a `YGO-SET` associated with it, and each `YGO-SET` has one of five `VARIANT-CONDITION` associated with that. The two together create a `YGO-SET-ITEM` which is where the inventory and pricing information is contained. - The information displayed is: `Card Name - Set Code - Set Edition - Set Rarity - Set Price` - Clicking the Gear displays the `YGO-SET-ITEM` for this particular card. - Editing of individual inventory items: [Edit #1](/cards/1/view) - Extraction of additional data on import: exact card name, set Code, Rarity, and Edition. - Import of YGOProDeck Extra data: passcodes and linked images based on passcodes ## Deck Builder The deck builder is located here: [/builder](/builder). The Deck Builder component currently supports searching by full card name name, e.g. `Magician of Faith`. Any text matching this pattern entered into the Deck List box will return a list of matching results. Currently, there are approximately 12000 entries in the database. This list came from the YGOProDeck API. ### How To Use It Simply paste a list of matching cards into the list. YGOProDeck Decks with extension `.ydk` can be uploaded with an incomplete public interface which can be found at [/ydk/](/ydk). ## User Interface The user interface is a [Caveman2](https://github.com/fukamachi/caveman) web app with Common Lisp back-end. All of the things that can be done on the web front-end have supporting code in the CL back-end. You may load the source code into your editor and mess around with card information yourself. ### How To Use It You're using it right now! ## Source Code The source code is available [here](http://[2601:198:100:1261:d250:99ff:fe2e:566a]/git/). # Completed Feature List ## Categories We're using the [Nested Set Model](https://en.wikipedia.org/wiki/Nested_set_model#Example). You may create Parent Nodes (Left) and Child Nodes (Right). It needs a lot of work and is pretty SQL heavy. ## Sort By Many Fields When searching for results, we try to support "Not Just Alphabetical," e.g. more than alphabetical sort. You may sort by Qty, Category, Race, Type, Card Text... Some of these aren't actually implemented because it's quite a bit of work. But the majority of the sort patterns are there. ## Deck Constraints The constraints placed on a deck during construction at the `/builder` resource are kind-of arbitrary. Here is the breakdown. First of all, at the database level, there are no restrictions on a deck. See [here](https://www.formatlibrary.com/decktypes/inzektor?format=ravine_ruler) for an example. You will notice in the "Popular Extra Deck Cards" area there are *20* cards. You may download the `.ydk` file from the `Download` button at the top. If you import this deck into the app, it will accept it as is. You will end up with an Extra Deck with 20 cards in it. This is intended. You may also notice, that, by design, when you create a new deck, there will be zero cards in it. This is allowed as well. However, if you continue to construct a deck, you will eventually be constrained to 60 cards in your main deck, as well as 15 cards in extra and side decks. There is no way to prevent this limiting from occurring. Ideally, I would like to have a way to switch between "free builder" and "constrained builder." A problem thus far has been "Where does the constraint checking happen?" And the current solution lies in the way the app is structured. So if you imagine each deck you construct as a template, then the deck builder is really a template constructor. There is a queue of Saved Deck Configurations, which can be categorized, with the [Categories](#categories) feature above. - Main deck max cards 60 - Side Deck max cards 15 - Extra Deck max cards 15 As it stands, these constraints are hard coded. I'm not sure how I would implement this, but if I were to, it would be something like, setting a cookie and doing constraint checking in-line with some kind of CLOS object. ### Card Priority Cards will be added in this order: - Drag and drop: the card goes where you dropped it, provided the above numeric constraints are met. - Right click: the card is added at the "end" of the deck list, in this order: main deck, extra deck, side deck, trying to meet the above numeric constraints. Following this, when you save a deck, a priority number is assigned to the card as follows: - "normal" 0 - "effect" 1 - "ritual" 2 - "fusion" 3 - "link" 4 - "skill" 5 - "synchro" 6 - "token" 7 - "xyz" 8 - "spell" 9 - "trap" 10 - "effect_pendulum" 11 - "fusion_pendulum" 12 - "normal_pendulum" 13 - "ritual_pendulum" 14 - "synchro_pendulum" 15 - "xyz_pendulum" 16 - Everything Else 17 Lower numbers get put "earlier" in the deck listing. The next time you load the deck it will be sorted in this order. ## User Profiles You may currently register, login, logout, view the user list. This code has hardly been touched since it was implemented. If I spent more time working on the user code, I could also implement the "free builder" toggle system. The web framework system we're using gives us access to request and session information, and we can store cookies. There is also a database extension for managing all of this information persistently in a database. Our current database model is very simple. There is a user, with a password, and some metadata. We currently hash passwords, as well. So your passwords are stored securely. You currently may not change your password. When you register an account we ask for an email. We currently do nothing with this. An email server would take additional time to configure. A rudimentary setup would most likely be caught in your spam filters. This also highlights another issue with the app. We don't currently have a domain name. But that is another topic. ### Trade Between Profiles Theoretically this is no different than assigning a `category_id` to a `ydk_deck`. Simply add a `user_id` field to indicate the user which created the deck. However, this is not implemented, because I have not spent the required time looking at user management, as stated above. ## Charts / Metrics We have rudimentary charts and metrics provided by [RRDtool](https://oss.oetiker.ch/rrdtool/). These charts are just host information. We can feed it all kinds of data. It will take time to research the data format it ingests and how to produce a chart. I'm not sure if Crystal Commerce offers pricing or inventory charts or metrics. ## Picture of Finalized Deck We use [ImageMagick](https://www.imagemagick.org/) to generate deck images and other various image manipulations. We have complete control over the process. Currently output is very rudimentary. However I have complete control over the pipeline, and at this stage, more time could be spent developing this pipeline. It is currently sufficient for our purposes. The output is currently four static images, the main deck, extra, and side decks, then a concatenation of the three images. Additionally, we output the intermediate concatenation images as well. ## Different Card Games This is possible, all of the application is currently hard-coded to use Yu-Gi-Oh!. It would take a quite a bit of time to re-factor all of the routes to handle this scenario instead of possibly just running multiple copies of the app, or having dedicated instances of the app connected to dedicated database back-ends. Regardless, currently we only support Yu-Gi-Oh!. If more work were done on the User component, I could make it configurable as a cookie. ## Builder Controls Click on a card in the search results to see its information (card text, ATK, DEF, ...). ### Advanced Search In the Advanced Search menu you may search by card type, e.g. `frame_type` => `trap` will show you all trap cards. ## Decks Overview There is currently a rudimentary decks overview page. ## Constructed Deck Workflow The workflow for constructing decks is as follows: 1. Create deck of cards. Currently we select from all cards. Maybe we should just select cards from inventory. The majority of this functionality in place and isn't expected to change. A deck will always just be a list of cards plus metadata. 2. The deck of cards has metadata about author, name of deck, time of creation. The main content of the deck is three lists, comprising the main, extra, and side decks. This information is not expected to change in the future. Decks created by a particular user for example. The underlying metadata representation is what's being worked on. Currently each item in the database has all information duplicated from the rest of the database. Changing the price for one card changes the price for only that one card matching that row in the database. There will be additional tables to store pricing information in the next step. 3. On the Deck Overview page, selecting "Pull Deck" will decrease the inventory of the lowest priced card in inventory by one for every card in the deck. This is like "add to cart" in an online shopping platform, with additional inventory keeping. This is analogous to the deck construction step, except instead of selecting cards to be put into a deck, that information is provided prior, and we use that list of information to construct secondary lists. 4. On the pulled deck page, for every card in the deck, you will be able to select cards by edition, condition, and rarity of every card in the inventory matching that card's passcode. I can conceive a very simple concept where you attempt to check out, and then are returned with error messages saying which items had errors. This is the current approach. 5. There will be an intermediate stage. Once there is enough inventory and the deck is "pulled" it will enter an area where each individual card will be selected. e.g. selecting the rarity or set of a particular card in each deck. 6. Once all "errors" are resolved (banlists, constraints, etc), the "pulled" deck will allow you to "construct" it, which will finalize the state of this pulled deck in the database, moving it to another table, the list of decks for sale. 7. The list of decks for sale is just pulled, constructed decks with pricing information attached and whether or not it was sold and what price it was sold at and when. ## Formats It appears that I began working on format integration from YGOProDeck. I have not found a way to integrate this information into the builder yet.