301 Days

A year of gamedev experiments.

Day 63 - Ring-a-ding-ding

| Comments

In which we find out how hard it is to get a cool ring.

Give me the Ring

So we still need to test this RequireMakeRecallReagent option. For the negative case, we start with:

features/config_file.featurelink
244
245
246
247
248
249
250
251
252
253
Scenario: RequireMakeRecallReagent False, thief can make recall ring from nothing
      Given I use the "minimal" database
      And I add player and character "TestThief01"
      And I make the character a thief
      And I give the character the spell "makerecall" 
      And the server is started
      When I log on as "TestThief01"
      And I enter the game
      And I cast the spell "makerecall"
      Then I have a recall ring in my right hand

for which we need to add a bunch of stuff. Updating a player class/alignment/etc, adding a spell to a player’s repertoire, casting a spell, and checking our hands. We add the spells back into the minimal database rather than having to create them from scratch, and instrument everything up to the casting of the spell…

but it doesn’t work.

1
2
3
4
5
6
7
 And I cast the spell "makerecall"                                               # features/steps/character_steps.rb:7
 Sending na na na na and waiting for / ->/...
...
\e[1;32mR undefined\e[0m\e[24;1H                             
\e[24;1H \e[1;32mL undefined\e[0m\e[23;42H      \e[23;30H\e[35mHits       : 36/36    
\e[0m\e[23;72H      \e[23;60H\e[35mHits Taken : 0\e[0m\e[25;42H     \e[25;30H\e[35mStamina    : 10
\e[0m\e[24;42H        \e[24;30H\e[35mExperience : 4996  \e[0m\e[11;1HI don't understand your command.

(Yes, I still need to work on better output of the terminal control codes.)

Hmmm. “na na na na” is the chant I set for the spell, but I’m getting a bad command response. Let’s make sure chanting works at all by trying to summon a demon:

1
2
3
Sending alsi ku nushi ilani and waiting for / ->/...
...
\e[0m\e[11;1HYou hear a voice in your head: 'Not now i'm busy.'\n\r\e[21;1H ->

So that worked.

Check the book

The database looks correct to me, so we’ll try the one way that players can check the spells available: we’ll put his spellbook in his hand and look at it.

features/config_file.featurelink
244
245
246
247
248
249
250
251
252
253
254
255
256
Scenario: RequireMakeRecallReagent False, thief can make recall ring from nothing
      Given I use the "minimal" database
      And I add player and character "TestThief01"
      And I make the character a thief
      And I give the character the spell "makerecall"
      And I put a spellbook in the the character's right hand
      And the server is started
      When I log on as "TestThief01"
      And I enter the game
      And I read the book
      And I warm the spell "Make Recall"
      And I cast the warmed spell
      Then I have a recall ring in my left hand

And the book doesn’t even show up in his hands. Turns out I was deleting the player out from under myself as part of the log on step:

features/steps/login_steps.rblink
181
182
183
When(/^I log on as "([^"]*)"$/) do |name|
  @user = { acct_name: name, acct_password: "password" }
  ensure_standard_account_exists(@user[:acct_name], @user[:acct_password])
features/lib/db_helper.rblink
92
93
94
95
96
97
98
99
100
101
102
def ensure_standard_account_exists(acct_name, acct_password)
  accountID = find_or_create_account(acct_name, acct_password)
  # now that we have an accountID we can make the player
  client = connect_to_db(@server_database)
  # first delete any players already attached to this accountID
  query = "DELETE \
    FROM [#{@server_database}].[dbo].[Player]
    WHERE [accountID] = #{accountID}"
  result = client.execute(query)
  affected_rows = result.do
  puts "Pre-existing players for account ID #{accountID} deleted: #{affected_rows}"

Oops.

Instead, let’s switch to a less scorched earth model.

features/lib/db_helper.rblink
95
96
97
98
99
100
101
102
def ensure_standard_account_exists(acct_name, acct_password)
  accountID = find_or_create_account(acct_name, acct_password)
  @user[:char_name] = acct_name + '_name'
  # now that we have an accountID we can make the player
  desired_player = {accountID: accountID, account: acct_name, name: @user[:char_name]}
  unless player_exists(desired_player)
    client = connect_to_db(@server_database)
    # first delete any players already attached to this accountID
features/lib/db/player.rblink
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def player_exists(player_hash)
  client = connect_to_db(@server_database)
  query = "SELECT [name], [playerID] FROM [#{@server_database}].[dbo].[Player] WHERE "
  conditions = []
  player_hash.keys.each do |key|
    if player_hash[key].is_a?(String)
      conditions << "#{key.to_s} = '#{player_hash[key]}'"
    else
      conditions << "#{key.to_s} = #{player_hash[key]}"
    end
  end
  query += conditions.join(" AND ")
  puts "Query is #{query}"
  result = client.execute(query)
  row = result.each(:first => true)
  puts row.inspect
  result.affected_rows > 0
end

A little awkward and subject to further refactoring, but it should do what we want.

Great success!

After learning a few things, like:

  • An item can’t have a created-on date of NULL, or the server will choke on it.
  • A player can only read a spellbook that is “attuned” to them. Otherwise it’s glued shut.
  • The parser’s not quite up to “look at ring in left hand”; “look in left hand” works.

Ultimately I don’t need the spellbook code, but left it in as a cool in-game verification for the spell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
R spellbook                              L                 
Hits       : 36/36          Hits Taken : 0     Stamina    : 10        Experience : 4996       Magic Points: 10 
->
    And I read the book                                                             # features/steps/character_steps.rb:17
      Sending read book and waiting for / ->/...
...
R spellbook                              L                 
Hits       : 36/36          Hits Taken : 0     Stamina    : 10        Experience : 4996       Magic Points: 10
Page 1:
      
The incantation for Make Recall (makerecall)
      
na na na na
      
 ->
    And I warm the spell "Make Recall"                                              # features/steps/character_steps.rb:12
      Sending na na na na and waiting for / ->/...
...
R spellbook                              L                 
Hits       : 36/36          Hits Taken : 0     Stamina    : 10        Experience : 4996       Magic Points: 10
      You warm the spell Make Recall.
      
 ->
    And I cast the warmed spell                                                     # features/steps/character_steps.rb:22
      Sending cast and waiting for / ->/...
...
R spellbook                              L ring      
Hits       : 36/36          Hits Taken : 0     Stamina    : 10        Experience : 4996       Magic Points: 4 
->
    Then I have a recall ring in my left hand                                       # features/steps/character_steps.rb:26
      Sending look in left hand and waiting for / ->/...
...
R spellbook                              L ring      
Hits       : 36/36          Hits Taken : 0     Stamina    : 10        Experience : 4996       Magic Points: 4
You are looking at a small gold ring. It is emitting a faint blue glow. The ring is worth 150 coins.
->

The above is heavily edited. Need to work on that ouput formatting. Tomorrow.


Useful Interesting Stuff


Day 63 code - tests

Comments