Yu-Gi-Oh! Deck Building and Card Inventory Management web interface written in Common Lisp, utilizing HTMX.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

12KB

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 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:

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 using Caveman2.

Inventory Management

The inventory manager is located here: /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

  • 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

  • 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.

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/.

User Interface

The user interface is a Caveman2 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.

Completed Feature List

Categories

We're using the Nested Set Model.

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 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 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. 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 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, ...).

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.