This simple application detects the user\'s home directory, detects how
the operating system finds its way to the home directory, parses the INI
file, and then increments the `level` entry for `player1` by 1.

Save the file. Change to the `~/config` directory in a terminal, and
then try running the application (it will fail, but that\'s
intentional).

    $ lua ./main.lua
    lua: ./main.lua:4: module 'inifile' not found...

This tells you that Lua attempted to use the `inifile` library, but
couldn\'t locate it because the library is\'t installed on your system,
it\'s installed in your project directory.

Lua itself substitutes `?` with the *the name of the library you provide in `require` statements*.


The end results of the commands are the same: you get the path to the
library or libraries you need to add to the very top of your `main.lua`
code:

    

This simple statement sets `package.path` to be *whatever it already
is*, and then appends (..) the `local` directory. It also replaces any
instance of `?` with *whatever is being required*.

::: {.note}
If you read other people\'s Lua code, you might see the alternate method
of pointing Lua to a library. Sometimes, a programmer provides the path
to the library manually in the `require` statement, using dots as
delimiters: `require('lib.inifile.inifile')`.

This isn\'t wrong or bad, but it is very specific to a *single* library
file. Not all libraries consist of just one file, so that method is less
flexible than providing the `package.path`.
:::

Try your program again. This time, it is successful:

    $ lua ./main.lua
    slasher
    7
    zombie,vampire

The file was parsed correctly. Now check the original `sample.ini` file
to see if player1\'s level was updated. To see the contents of a file
quickly in a terminal, you can use the `cat` command, which is short for
*concatenate* (so you are, in effect, concatenating the file to nothing,
so its contents are just printed to your terminal).

    $ cat ~/sample.ini
    [player1]
    name= slasher
    defeated = zombie,vampire
    level=8

    [player2]
    name= vecna
    defeated = vampire,gug,shantak
    level=8

Lua has parsed, read, and written a plain text configuration using a
local library.

Deck building {#db-deck}
-------------

Having completed the exercise in this chapter, you not only know how to
store data on your user\'s computer, but you also know how to define
data structures in a file to have it imported by your application. That
means you don\'t have to define a deck of complex battle cards in the
main code of your application, which means a smaller file for your
executable code, and a lot less clutter in your main script.

For the Blackjack game, the card deck was a simple 52 card poker deck.
Your current project, Battlejack, can use a standard card deck, but part
of the fun of programming digitally is that you can generate game assets
without the costly manufacturing bills involved in creating a new deck
of cards in the physical world. It doesn\'t make sense to limit the game
to a standard poker deck when you can, instead, invent any theme you
want for your game.

Regardless of your artistic skill or access to artwork, 52 cards is a
lot of cards to make. It\'s not impossible (there are over 10,000 Magic:
The Gathering cards, and 2,000 in Magic Online) but for an independent
game developer it\'s a tall order. When determining the assets for a
game, it\'s important to look critically at what is necessary and what
is just nice to have.

For this project, even though the design assets were 52 cards, there
were actually only 10 unique values: 1 through 10. For every iteration
of cards 1 to 10, there were three cards worth 10 (Jack, King, Queen).

Furthermore, although the dev deck had 4 suits, the suits actually had
no effect on the game, so those can be thrown out. To create player
identities, the alpha version of the game used red and black, and since
that\'s easy and classic, the digital version can keep that. For
accessibility, the digital version will also use a symbol along with the
opposing colors, since not everyone can see the color red.

To make the game a little more exciting, the digital version of
Battlejack will enable players to \"level up\" as they continue to play.
Levels in any game are a mix of rewards and, essentially, penalties; the
players levels up and becomes more powerful, but only to face new
challenges. That means the digital deck will have a small subset of
extra cards that get shuffled into the game, throwing off the
predictability of how often certain values get drawn, and a second
subset of cards that serve as \"power ups\", granting the player a free
bonus, anywhere from a +1 to +3, to their hand.

There isn\'t much to this dataset, but it should be expressed separately
from the user data because it is not data that is meant to change. It
defines the virtual deck of cards, and that\'s all. Tracking which cards
have been drawn during a game must be done by the application itself,
because it gets reset every time a new game is started. Any permanent
rewards or penalties or level data gets written to the user data file.

Take a moment to think about what kind of deck you want to use for your
Battlejack implementation, or download and use the deck provided with
this book (the art is licensed under a Creative Commons license, so you
may use the artwork for any purpose). Once you have decided on a theme,
create a project folder called `battlejack`. Create `font` and `img`
directories within your project folder, as usual.

Create a deck definition file called `deck.ini` and save it into your
project directory. You know that the card dealer library you made for
Blackjack uses random numbers to select a card, so the key term in the
definition file must be a number, meaning that the value must hold both
the face and card value of the card.

You can customize the definition file to suit your custom theme, or if
you are using the art available with this book, you can use this:

    [card]
    1 = mystic,1
    2 = bard,2
    3 = arcanist,3
    4 = archer,4
    5 = goblin,5
    6 = construct,6
    7 = cavalry,7
    8 = priest,8
    9 = fighter,9
    10 = wizard,10
    11 = cavalry,10
    12 = knight,10

    [earn]
    1=zealot,6
    2=cultist,7
    3=charm,8
    4=orc,9
    5=god,10

    [up]
    1=sun,1
    2=bird,1
    3=sword,1
    4=ram,2
    5=skull,2
    6=templar,2
    7=weep,3
    8=plague,3

This isn\'t the only way to create a deck definition, and using an INI
file isn\'t the only format, but because it has a nice, simple
dependency and the definition is not complex, it works well for this
project.

Here\'s an example of how it can be used. This sort of code selects a
card from the `[card]` deck:

    > print(deck['card'][tostring(2)])
    mystic,1
    > print(deck['card'][tostring(12)])
    knight,10

The code you use in the actual Battlejack game will require randomness,
and must parse the face from the card value (separated by a comma), but
those are details for later.

This deck provides just 25 cards to generate. That\'s manageable, so now
all that\'s left is to make them. And that\'s just what you\'ll do in
the next chapter.

Homework {#db-work}
--------

Installing and learning new libraries is an important part of
programming. Nobody codes everything from scratch unless absolutely
necessary, because there are so many great libraries out there with much
of your work already done for you.

Try these hacks:

-   INI files store key and value pairs; one word correlates to exactly
    one other word or number. For more complex data structures, there is
    a format called YAML, which allows you to define multiple levels of
    information for everything in your data set.

    Install `lua-yaml` or a similar library for parsing YAML and try to
    parse some sample data.

    For an example of a working script, download the code files for this
    chapter from this book\'s code repository.