316 lines
12 KiB
Markdown
316 lines
12 KiB
Markdown
|
# 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.
|