Compare commits

...

37 Commits

Author SHA1 Message Date
5312e322f0 Firelights: inventory, relics and starting vehicle implemented. 2023-12-20 19:06:51 -05:00
f2a5a74ca8 Firelights: Refactoring cards deck, adding StoryNode(s) and improving stories storage. 2023-12-20 13:20:14 -05:00
02d36190c2 Firelights: Character approaches and starting world map. 2023-12-08 14:03:28 -05:00
03cb4609eb Firelights: Main character info. 2023-12-08 13:28:59 -05:00
7c454b41c2 Starting main character creation. 2023-12-08 12:45:43 -05:00
981712c32b Renaming before introducing characters and world map. 2023-12-06 07:41:39 -05:00
6bfb07dba9 Default UI. 2023-12-03 17:40:36 -05:00
dd23cd83d5 Dice pool creation. 2023-12-03 15:32:32 -05:00
3da183fe80 Rolling dice support started. 2023-12-03 14:48:29 -05:00
a9d376b36c Exporting oracles in STON and JSON. 2023-12-01 11:45:13 -05:00
29a8d52f0f Collecting oracles from template wiki. 2023-11-29 11:24:01 -05:00
6815aa9158 Collecting oracles from template wiki. 2023-11-28 13:55:12 -05:00
8a1d90d06f Modelation of Firelights/Vivarim TTRPGs started. 2023-11-28 12:58:47 -05:00
014eba5937 Recovering game reseting from last crash. 2023-11-28 12:07:32 -05:00
7772524569 Reseting and restarting a game. 2023-11-26 13:06:04 -05:00
5feee250e4 Improved printing. 2023-11-26 11:21:51 -05:00
1be8c6ba58 Drawing cards. 2023-11-14 19:13:59 -05:00
edfe4740b8 Card suits and initialization finished. 2023-11-14 11:21:21 -05:00
63c68c7232 Card suits and initialization. 2023-11-14 10:42:46 -05:00
dd5bf4cb33 Modelling deck of cards started. 2023-11-13 21:03:37 -05:00
dbbbd22483 Actualizar 'README.md' 2022-07-26 13:21:50 -05:00
be5f3fe2da Abilities use WikiText links now since they're imported. 2022-07-22 20:18:11 -05:00
7d8d183bf4 Updating assets classification. 2022-07-22 19:01:40 -05:00
a9f96e335f Updating data scrappers to new JSON data format and location. 2022-07-22 18:49:27 -05:00
66526fb8da Improving oracles options exportation. 2022-01-10 18:45:50 -05:00
67be117367 Oracles importation improved. 2021-12-05 13:58:22 -05:00
7c8c897d60 Modularizing the code. 2021-11-22 12:25:48 -05:00
40ab1d0000 Refactoring. New and improved SfPlayerCharacter to model character sheets. 2021-11-17 11:14:12 -05:00
62756bf703 Modelling player characters and starting a scafolding "protobot". 2021-11-16 19:23:50 -05:00
bd1257de86 Improving and cleaning: classes should take care of initializing simple objects collection of instances without creating new objects for that exclusive taks. 2021-11-10 15:45:32 -05:00
d004a7ec55 Minor refatorings. 2021-11-10 10:51:36 -05:00
be75aaea9f Actualizar 'README.md' 2021-11-10 10:11:17 -05:00
3f0ba1a605 Improved installed instructions. 2021-11-10 10:09:59 -05:00
4aaec17473 Actualizar 'README.md' 2021-11-09 17:16:12 -05:00
b3604a0700 Defining basic baseline. 2021-07-24 09:11:45 -05:00
f5edec4708 Improving oracles' import/export. 2021-07-06 12:20:25 -05:00
9f8556bfa3 Fixing loading problem. 2021-06-20 15:10:07 -05:00
156 changed files with 786 additions and 56 deletions

View File

@ -0,0 +1,5 @@
{
"separateMethodMetaAndSource" : false,
"noMethodMetaData" : true,
"useCypressPropertiesFile" : true
}

View File

@ -0,0 +1,8 @@
baselines
baseline: spec
<baseline>
spec
for: #common
do: [
spec package: 'RoloLudo'
]

View File

@ -0,0 +1,3 @@
accessing
projectClass
^ MetacelloCypressBaselineProject

View File

@ -0,0 +1,11 @@
{
"commentStamp" : "",
"super" : "BaselineOf",
"category" : "BaselineOfRoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [ ],
"name" : "BaselineOfRoloLudo",
"type" : "normal"
}

View File

@ -0,0 +1 @@
SystemOrganization addCategory: #BaselineOfRoloLudo!

View File

@ -0,0 +1 @@
(name 'BaselineOfRoloLudo')

View File

@ -0,0 +1 @@
{ }

View File

@ -1,3 +1,28 @@
# RoloLudo
Utilities for table top role playing, starting with Ironsworn.
Utilities for table top role playing, starting with [Ironsworn](https://www.ironswornrpg.com/),
[Starforged](https://www.ironswornrpg.com/product-ironsworn-starforged)
and [Firelights](https://firelights.farirpgs.com/).
To install it on Pharo/GToolkit first install [ExoRepo](https://code.tupale.co/Offray/ExoRepo)
and then run from a Playground:
```smalltalk
ExoRepo new
repository: 'https://code.sustrato.red/Offray/RoloLudo';
load.
```
The first utilities connect JSON oracles with the [502Lab wiki](https://mutabit.com/repos.fossil/502Lab/uv/wiki/502Lab.html#) to facilitate translations.
In the future it is expected to incorporate different utilities to make the game experience more fluid and minimalistic:
* [x] Virtual dice.
* [x] Querying of oracles and wiki.
* [ ] Bots connected to Telegram or other game channels.
* [ ] Querying and editing of character sheets.
**References**:
* [Dataforged](https://github.com/rsek/dataforged): Official Ironsworn: Starforged rules data in JSON, for use in community tools.
* [Datasworn](https://github.com/rsek/datasworn): JSON files of game data for the tabletop role-playing game Ironsworn, and its expansion, Ironsworn: Delve. For use in community-created tools, since it doesn't make sense to duplicate work on data entry.
* [Stargazer conversions](https://github.com/nboughton/stargazer_conversions): This project provides scripts to convert JSON content forged with rsek data to match the models used in the Stargazer project.

View File

@ -0,0 +1 @@
I represent a deck of cards. The terminology was taken from [Glossary of card game terms](https://en.wikipedia.org/wiki/Glossary_of_card_game_terms) in Wikipedia.

View File

@ -0,0 +1,10 @@
accessing
cards
| response |
response := OrderedCollection new.
self suits keysDo: [:suit |
(self numeralCards, self faceCards) do: [:number|
response add: number asString, suit.
].
].
^ response

View File

@ -0,0 +1,3 @@
accessing
faceCards
^ #( 'J' 'Q' 'K')

View File

@ -0,0 +1,3 @@
accessing
numeralCards
^ 1 to: 10

View File

@ -0,0 +1,6 @@
accessing
suits
^ { '♣' -> 'clubs' .
'♦' -> 'diamons' .
'♥' ->'hearts' .
'♠' ->'spades'} asDictionary

View File

@ -0,0 +1,3 @@
accessing
cards
^ self class cards

View File

@ -0,0 +1,6 @@
accessing
draw: card
self stock
detect: [ :each | each = card ]
ifFound: [self drawn add: card ]
ifNone: [ ^ nil ]

View File

@ -0,0 +1,6 @@
accessing
draw
| taken |
taken := self stock atRandom.
self drawn add: taken.
^ taken

View File

@ -0,0 +1,3 @@
accessing
drawAll: aCollection
self drawn addAll: aCollection

View File

@ -0,0 +1,3 @@
accessing
drawn: aCollection
drawn := aCollection

View File

@ -0,0 +1,3 @@
accessing
drawn
^ drawn ifNil: [drawn := OrderedCollection new]

View File

@ -0,0 +1,12 @@
accessing
printOn: aStream
super initialize.
aStream nextPutAll: 'Stock: ', String cr.
self class suits keysDo: [ :suit |
aStream
nextPutAll: (self stockCardsInSuit: suit);
nextPutAll: String cr.
].
aStream nextPutAll: 'Drawn: ', String cr.
self drawn do: [:card | aStream nextPutAll: card, ' ' ].
^ aStream contents.

View File

@ -0,0 +1,5 @@
accessing
reset
self drawn: OrderedCollection new.
self stock: self class cards.
^ self

View File

@ -0,0 +1,3 @@
accessing
stock
^ stock := self class cards copyWithoutAll: self drawn

View File

@ -0,0 +1,7 @@
accessing
stockCardsInSuit: aString
| response suitCards |
response := '' writeStream.
suitCards := self stock select: [ :card | card endsWith: aString ].
suitCards do: [ :card | response nextPutAll: card ].
^ response contents

View File

@ -0,0 +1,6 @@
accessing
uiCardsFor: aView
<gtView>
^ aView text
title: 'Cards';
text: [ self printString ]

View File

@ -1,13 +1,14 @@
{
"commentStamp" : "GlamorousAuthor 5/17/2021 16:41",
"commentStamp" : "<historical>",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"items"
"drawn",
"stock"
],
"name" : "SfAssets",
"name" : "DeckOfCards",
"type" : "normal"
}

View File

@ -0,0 +1,3 @@
accessing
dice: anArray
dice := anArray

View File

@ -0,0 +1,3 @@
accessing
dice
^ dice ifNil: [dice := Array new ]

View File

@ -0,0 +1,5 @@
accessing
printOn: aStream
super initialize.
aStream
nextPutAll: self dice printString

View File

@ -0,0 +1,3 @@
accessing
roll
^ self dice collect: [:each | each roll ]

View File

@ -0,0 +1,14 @@
accessing
uiDiceFor: aView
<gtView>
| response currentRoll dicePool |
response := '' writeStream.
currentRoll := self roll.
dicePool := self dice collect: [:each | each faces ].
response
nextPutAll: 'Dice: ', dicePool printString ; cr;
nextPutAll: 'Roll: ', currentRoll printString; cr;
nextPutAll: 'Sum: ', currentRoll sum asString.
^ aView text
title: 'Dice';
text: [ response contents ]

View File

@ -0,0 +1,4 @@
accessing
with: fistInteger with: secondInteger
self dice: (Array with: (Die with: fistInteger) with: (Die with: secondInteger))

View File

@ -0,0 +1,13 @@
{
"commentStamp" : "",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"dice"
],
"name" : "DicePool",
"type" : "normal"
}

View File

View File

@ -0,0 +1,4 @@
accessing
with: anInteger
^ self new
faces: anInteger

View File

@ -0,0 +1,3 @@
accessing
faces: anInteger
faces := anInteger

View File

@ -0,0 +1,3 @@
accessing
faces
^ faces

View File

@ -0,0 +1,5 @@
accessing
printOn: aStream
super initialize.
aStream
nextPutAll: self faces asString

View File

@ -0,0 +1,3 @@
accessing
roll
^ self faces atRandom

View File

@ -0,0 +1,13 @@
{
"commentStamp" : "",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"faces"
],
"name" : "Die",
"type" : "normal"
}

View File

@ -0,0 +1,9 @@
accessing
approaches
^ approaches ifNil: [
approaches := OrderedDictionary new
at: 'Strong' put: 0;
at: 'Patient'put: 0;
at: 'Quick' put: 0;
yourself
]

View File

@ -0,0 +1,6 @@
accessing
inventory
^ inventory ifNil: [
inventory := Dictionary new
at: 'vehicle' put: self vehicle;
yourself]

View File

@ -0,0 +1,3 @@
as yet unclassified
name: aString
name := aString

View File

@ -0,0 +1,3 @@
accessing
name
^ name

View File

@ -0,0 +1,3 @@
accessing
patient: anInteger
self approaches at: 'Patient' put: anInteger

View File

@ -0,0 +1,3 @@
accessing
patient
^ self approaches at: 'Patient'

View File

@ -0,0 +1,10 @@
accessing
printOn: aStream
super initialize.
aStream
nextPutAll: '- Name: ', self name; cr;
nextPutAll: '- Pronouns: ', self pronouns; cr;
nextPutAll: '- Approaches'; cr;
nextPutAll: ' - Strong: ', self strong asString; cr;
nextPutAll: ' - Patient: ', self patient asString; cr;
nextPutAll: ' - Quick: ', self quick asString; cr

View File

@ -0,0 +1,3 @@
accessing
pronouns: aString
pronouns := aString

View File

@ -0,0 +1,3 @@
accessing
pronouns
^ pronouns

View File

@ -0,0 +1,3 @@
as yet unclassified
quick: anInteger
self approaches at: 'Quick' put: anInteger.

View File

@ -0,0 +1,3 @@
accessing
quick
^ self approaches at: 'Quick'

View File

@ -0,0 +1,3 @@
accessing
relics
^ self inventory at: 'relics' ifAbsentPut: [ nil ]

View File

@ -0,0 +1,3 @@
accessing
strong: anInteger
self approaches at: 'Strong' put: anInteger

View File

@ -0,0 +1,3 @@
accessing
strong
^ self approaches at: 'Strong'

View File

@ -0,0 +1,6 @@
accessing
uiViewFor: aView
<gtView>
^ aView text
title: 'Character Info';
text: [ self printString ]

View File

@ -0,0 +1,4 @@
accessing
vehicle
"This should be replaced y a Vehicle inventory item, with fatigue status."
^ 'criocápsula móvil'

View File

@ -0,0 +1,16 @@
{
"commentStamp" : "",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"name",
"pronouns",
"inventory",
"approaches"
],
"name" : "FirelightsCharacter",
"type" : "normal"
}

View File

@ -0,0 +1,3 @@
accessing
characters
^ characters ifNil: [ characters := OrderedCollection new]

View File

@ -0,0 +1,3 @@
accessing
deck: anObject
deck := anObject

View File

@ -0,0 +1,3 @@
accessing
deck
^ deck ifNil: [ deck := DeckOfCards new]

View File

@ -0,0 +1,3 @@
accessing
dice
^ dice ifNil: [ dice := DicePool new with: 6 with: 6 ]

View File

@ -0,0 +1,10 @@
accessing
export
| response |
response := '' writeStream.
(STON writer on: response)
newLine: String lf;
prettyPrint: true;
keepNewLines: true;
nextPut: self.
^ MarkupFile exportAsFileOn: FileLocator temp / 'firelights.ston' containing: (response contents)

View File

@ -0,0 +1,3 @@
accessing
loadOraclesFromRepository
^ STON fromString: 'https://mutabit.com/repos.fossil/502Lab/raw/f0c299?at=oracles.ston' asUrl retrieveContents utf8Decoded

View File

@ -0,0 +1,18 @@
accessing
loadOraclesFromWikiTemplate
| oraclesTiddler rows |
oraclesTiddler := self wiki templateWiki tiddlers
detect: [:tiddler | (tiddler title) = 'Tablas Generadoras' ].
rows := oraclesTiddler text lines allButFirst collect: [:each | each splitOn: '|'].
^ rows collect: [:row | | tempDice |
tempDice := (row second splitOn: '"') second.
tempDice := tempDice splitOn: Character space.
tempDice := { tempDice first asNumber . tempDice second asNumber }.
OrderedDictionary new
at: 'dice' put: tempDice;
at: 'region' put: row third;
at: 'theme' put: row fourth;
at: 'event' put: row fifth;
at: 'past' put: row sixth;
yourself.
]

View File

@ -0,0 +1,3 @@
accessing
namesOracle
^ SfOracle new loadCharacterNames options

View File

@ -0,0 +1,4 @@
accessing
newMainCharacter
self characters ifEmpty: [ self characters add: FirelightsCharacter new].
^ self characters first.

View File

@ -0,0 +1,3 @@
accessing
oracles: aDictionary
oracles := aDictionary

View File

@ -0,0 +1,3 @@
accessing
oracles
^ oracles ifNil: [ oracles := self loadOraclesFromRepository]

View File

@ -0,0 +1,5 @@
accessing
queryOracles
| currentRoll |
currentRoll := self roll.
^ self oracles detect: [ :each | (each at: 'dice') = currentRoll ] ifNone: [ ^ currentRoll ]

View File

@ -0,0 +1,8 @@
accessing
randomName
| response|
response := self namesOracle.
^ {'Given name' -> (response at: 'givenNames') atRandom.
'callsign' -> (response at: 'callsigns') atRandom.
'Familiy name' -> (response at: 'familyNames') atRandom.
} asDictionary.

View File

@ -0,0 +1,4 @@
accessing
resetWorlMap
self worldMap: nil.
self deck reset.

View File

@ -0,0 +1,3 @@
accessing
roll
^ self dice roll

View File

@ -0,0 +1,11 @@
accessing
saveOracles
| fileName formats |
fileName := 'oracles'.
formats := {'ston' -> STON. 'json' -> STONJSON} asDictionary.
formats keysAndValuesDo: [:format :class |
MarkupFile
exportAsFileOn: (FileLocator temp / fileName), format
containing: (class toStringPretty: self oracles)
].
^ FileLocator temp

View File

@ -0,0 +1,3 @@
accessing
story: anObject
story := anObject

View File

@ -0,0 +1,3 @@
accessing
story
^ story ifNil: [ story := OrderedCollection new]

View File

@ -0,0 +1,13 @@
accessing
uiGameFor: aView
<gtView>
| response |
response := '' writeStream.
response
nextPutAll: '❭❭❭ Main Character'; cr; cr;
nextPutAll: self characters first printString; cr;
nextPutAll: '❭❭❭ Deck'; cr; cr;
nextPutAll: self deck printString.
^ aView text
title: 'Game';
text: [ response contents ]

View File

@ -0,0 +1,7 @@
accessing
wiki
^ wiki ifNil: [ wiki := TiddlyWiki new
name: 'Firelights/Vivarium games wiki';
template: 'https://vivarium.tiddlyhost.com/'.
]

View File

@ -0,0 +1,3 @@
accessing
worldMap: anObject
wordMap := anObject

View File

@ -0,0 +1,3 @@
accessing
worldMap
^ wordMap ifNil: [ wordMap := OrderedCollection new ]

View File

@ -0,0 +1,5 @@
accessing
worldMapDraw: aCardCollection
self deck drawn addAll: aCardCollection.
self worldMap addAll: aCardCollection.

View File

@ -0,0 +1,6 @@
accessing
worldMapDraw
| currentPlace |
currentPlace := self deck draw.
self worldMap add: currentPlace.
^ currentPlace

View File

@ -0,0 +1,19 @@
{
"commentStamp" : "",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"deck",
"dice",
"wordMap",
"oracles",
"wiki",
"characters",
"story"
],
"name" : "FirelightsGame",
"type" : "normal"
}

View File

@ -0,0 +1 @@
I model a simple bot to automatize some tasks related with rolling oracles, character creation and playin in general.

View File

@ -0,0 +1,9 @@
accessing
newRandomPlayerCharacter
^ SfPlayerCharacter new
momentum: 2;
maxMomentum: 10;
momentumReset: 2;
health: 5;
spirit: 5;
supply: 5.

View File

@ -0,0 +1,11 @@
accessing
rollDice
"For the moment, I will model a dice roll in Ironsworn Starforged.
A more abstract vocabulary should be deviced allowing the roll of
dice pool"
^ OrderedDictionary new
at: 'challenge die (1):' put: 10 atRandom;
at: 'action die:' put: 6 atRandom;
at: 'challenge die (2):' put: 10 atRandom;
yourself.

View File

@ -0,0 +1,11 @@
{
"commentStamp" : "<historical>",
"super" : "Object",
"category" : "RoloLudo",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [ ],
"name" : "LudoBot",
"type" : "normal"
}

View File

@ -2,5 +2,9 @@ I model an asset of the Ironsworn Starforged Tabletop Roleplaying Game.
More information at:
[1] https://www.ironswornrpg.com/
[2] https://www.kickstarter.com/projects/shawntomkin/ironsworn-starforged
[1] <https://www.ironswornrpg.com/>
[2] <https://www.kickstarter.com/projects/shawntomkin/ironsworn-starforged>
I use as inspiration the data provided by @rsek at this repostory:
<https://github.com/rsek/datasworn>

View File

@ -0,0 +1,9 @@
accessing
collectionFromRepository: jsonFileUrl language: isoCode
| rawData |
rawData := STON fromString: jsonFileUrl asUrl retrieveContents.
^ rawData collect: [:assetDict |
(assetDict at: #Assets) collect: [ :assetSubdict |
self new fromDictionary: assetSubdict; language: isoCode
].
]

View File

@ -0,0 +1,3 @@
accessing
collectionFromRepository
^ self collectionFromRepository: 'https://raw.githubusercontent.com/rsek/dataforged/main/dist/starforged/assets.json' language: 'en'

View File

@ -1,7 +1,3 @@
accessing
asJsonTiddler
<<<<<<< HEAD
^ self asTiddler asJson
=======
^ self asTiddler asJson
>>>>>>> master
^ self asTiddler asJson

View File

@ -1,3 +1,4 @@
converting
currentAbilities
^ self abilities at: 'enabled'

View File

@ -1,6 +1,6 @@
accessing
fromDictionary: aDictionary
name := aDictionary at: #Name.
category := aDictionary at: #Category.
abilities := self populateAbilities: (aDictionary at: #Abilities)
category := ((aDictionary at: 'Asset Type') splitOn: '/') last copyReplaceAll: '_' with: ' '.
abilities := self populateAbilities: (aDictionary at: #Abilities)

View File

@ -1,10 +1,12 @@
accessing
populateAbilities: abilitiesDictionary
populateAbilities: abilitiesArray
| enabled disabled |
enabled := abilitiesDictionary select: [ :abi | abi keys includes: 'Enabled' ].
disabled := abilitiesDictionary reject: [ :abi | abi keys includes: 'Enabled' ].
enabled := abilitiesArray select: [ :abi | (abi at: 'Enabled') = true ].
disabled := abilitiesArray select: [ :abi | (abi at: 'Enabled') = false ].
^ self abilities
at: 'enabled' put: (enabled collect: [:abi | (abi at: 'Text') ]);
at: 'disabled' put: (disabled collect: [:abi | (abi at: 'Text') ]);
at: 'enabled' put: (enabled collect: [:abi |
(WikiText new content: (abi at: 'Text')) convertMarkdownLinks ]);
at: 'disabled' put: (disabled collect: [:abi |
(WikiText new content: (abi at: 'Text')) convertMarkdownLinks ]);
yourself.

View File

@ -1,4 +0,0 @@
I model a collection of Starforged assets.
I use as inspiration the data provided by @rsek at this repostory:
https://github.com/rsek/datasworn

View File

@ -1,8 +0,0 @@
accessing
fromUrlString: aString language: isoCode
| rawData |
rawData := STON fromString: aString asUrl retrieveContents.
self items: ((rawData at: 'Assets') collect: [:assetDict |
SfAsset new fromDictionary: assetDict; language: isoCode ])

View File

@ -1,3 +0,0 @@
accessing
items: anObject
items := anObject

Some files were not shown because too many files have changed in this diff Show More