EDIT: I was using the exact same code as the tutorial during Add Setup Button section and getting nowhere; I later found out that my checker was flipped down, submerging my button into the table. Ludo Lodge helped me in surprising time. I love this channel.
@@LudoLodge Set Up Cards The button doesn't appear at all. I first discovered I had typed it into Lua, which is a rookie mistake, but my first time. But now that I've put it into UI, I'm still not getting anything.
I apologise for commenting on an older video but you're the only one who's been able to help me so far! This video got me setting up some card setup in my own mod very easily, but what I'm struggling with is doing the same for some custom Tokens as well. I just can't figure out how to correctly adjust the script to have it do the same thing, move Tokens to specific locations at the press of a button. Looking up answers online tends to find only half the answer, assuming you're already rather well versed in lua and sadly I'm totally new as of this week! Having been able to work this video out easily enough, I can't imagine it's that much harder to have the process work for Tokens as well. I was hoping a genius here might be able to give me some tips!
Excellent explanation. With my limited coding knowledge, I was able to follow along and understand what you're explaining without going back multiple times.
These are SO helpful. I just started working on putting a few of my prototype games into TTS. These scripting tutorials are making my life so much easier. Thank you.
Hey! Big props for including timestamps in your vid, this is extremely helpful. Especially thankful that you explain your reasoning for stuff but don't slow down your pacing by babying people who don't know basic coding ideas. Some people won't like that but I really appreciate it
I do have programming experience with Microsoft VBA and SQL but even so I feel that the scripting explanations given here are clear and simple enough for a complete beginner to use. Also it helps that the vocal performance is measured and delivered at a pace that makes it very easy to listen to. Having developed a card game using Microsoft Access previously, some of the syntax of the Lua language is very recognisable. Great work and I look forward to watching more.
it should be noted that placing the checker on the table does not create its button in the scripting. it is created by clicking rmb/scripting/scripting editor, then it appears. but it will disappear if there is nothing written in that window.
Thank you for the guide. Is there a video of you who teaches how to restart the game or begin another round with all cards and objects go back to first position?
perfect timing to upload this series. I just started learning a bit of LUA to script stuff in TTS . Gotta get my Information from so many sources, your Videos will be on of these sources and will help me a lot. I did all my buttons with LUA only, but XML seems to be a bit less messy in that regard, so I'm gonna try that too at some point. For now I want to stay with LUA.
This is so good! Thank you so much. Would you consider doing a video about cleaning up? For instance, say there are two different decks, and we need to gather all the cards of one type from the table and hands, and the other type of cards from the whole area or a discard pile.
This was fantastic. Thanks so much for these videos! Suggestion: If you destroy the button, the script is also destroyed and I've found that breaks my connection to VSCode and I can no longer edit that script. So, leave that out until it works as expected and add at the end. With this and your other videos, I was able to create setup scripts for two mods and a next turn setup for a 2nd mod.
I tried both the button and dealing a card and it was the most satisfying accomplishment in long time. You are an excellent instructor. Q: Is it possible to script a card to retain unique attributes regardless if it is in a deck or a single card? I'm going to be scripting zones next. Thank you.
I actually like the implementation you did for laying out cards in the video better than the one you gave in the overlay more in general. Say I want to lay cards/tiles over a board. The step taken from the deck to the first spot will likely be one distance, and the subsequent steps to lay out over spaces will be a different regularly repeated distance.
If that was the case, you could have the formula look something like deckPos[1] + 5 + (i * 3). The main point is that incrementing xPos is a little redundant since the i counter variable is already incrementing, but it works either way.
What is the ''unit'' that you went with ''1 + 3''? is it width of a card or is it what tts perceives to be an inch or a centimeter or something? or maybe some in game unit of measurement
Great Tutorial! Thanks!, now i can automate setup process on my prototype which have a couple of decks and some are being dealt to the players and some are dealt to the row on the board. I have 2 questions: 1. Is there any way to automatically snap cards dealt to the row to a snap point ? 2. Lets say i have a bag object with various tiles, at the start of the game i want to place them on the board in specific places (using snap points) Thanks and keep up this great work ! :)
Great video! I am trying to make a script to shuffle 24 card deck and then lay them out in a 4x6 grid (4 rows 6 columns). Is that possible with 1 click button, and if so how is that done?
Thanks for posting the code to GITHUB, and the other video on using onCHAT to test stuff out. I am trying to understand the WAIT function but the API is overwhelming me. I simply want to deal 3 cards to a zone that has an existing starting card - WAIT 3-5 seconds for the cards to get there, and then SHUFFLE them. Can you provide a working example of Wait that allows the PutObject command to finish? Thanks!
The Wait static class looks like it has several options for delaying the execution of code. For your use case, it sounds like you want to use Wait.time to specify a number of seconds. This would end up looking something like this: Wait.time(myFunction, 3) In this case, after 3 seconds, it will run the code in your function named "myFunction". So you could have a function named something like "shuffleDecks", and then use Wait.time(shuffleDecks, 3) after the code for dealing to the zones.
Thanks a lot! my TSS mod gets better with every video ;) I especially like that you already use good coding practice before it is even necessary, I know I would make mistakes everytime with changing GUIDs.
I really appreciate your videos. I do need your help however. Using your script, I made a button that deals 4 cards and another that draws 1 card. I want the draw card to draw a card ONLY for the player that clicks it. The issue is that every single player receives the drawn card and not just the person who pressed the button. Is there a way to adjust this?
Suppose I wanted to add scripting to a card. What functions does the card have inherently? Does a card lose its sense of self when it's put into a deck? (Will it lose its code in such a case?)
Thanks so much for this! It also worked taking tiles out of a bag and laying them out. Any advice on dealing a second row without having to make another button?
Thanks I'm completely new to scripting and these are really super helpful. would it be possible to set cards out like this to players depending on how many players are seated at the table. So that only players seated at the table would get cards into their hand and some out in front of them individually?
Thanks for the great tutorials! I was wondering though if it's possible to tell a button to take a specific card from the deck (or a specific object from inside another). For example, when the button is pressed I want the ace of spades to be taken from the deck and laid on the table.
You should be able to! The takeObject() method has optional parameters for either and index or GUID for the object to be taken: api.tabletopsimulator.com/object/#takeobject. As long as you have GUID of the card you want, you should be able to use that parameter to grab it specifically.
I have a grid of snap points that I've set to the same tag as the cards in a deck. They aren't the only snap points on the table but they are the only ones I want to use for that deck. Is it possible to pull the positions of those snap points so that when I run my script it places one card on each snap point? I found a getSnapPoints function but I don't know how to use it to do what I need, or if it's even possible.
It looks like "getSnapPoints()" will return a table of all the snap points (if you call it on Global), where each snap point is represented by another table that has some properties including tags: api.tabletopsimulator.com/object/#getsnappoints So it seems to me you might be able to do something like this (untested): local snapPoints = Global.getSnapPoints() -- Loop over each snap point for _, snapPoint in ipairs(snapPoints) do -- Loop over each tag on the snap point for _, tag in snapPoint.tags do -- If the tag matches our card tag, then take the card and put it at the snap point's position if tag == cardTag then deck.takeObject({flip=true, position=snapPoint.position}) end end end Hope that helps!
What if I wanted the number of cards to go down based on the number of players? I am not sure how I would write that out in the scripting. I feel like I would have to let TTS know that if there are 3 players, then draw 3 cards, but if there are 4 players, then draw 2 cards. Not sure how to do that though.
How would you change this if you wanted a button that was used to draw cards based on empty spaces on the field? For context I have a store in my game. I want to create a button that will draw and place cards only in spots that have an empty space because a player has bought 1 or more cards from the store.
So i followed through woth making the button its self. And everything matches. But the button is streched across the table in lenght. But width and hight is right
I want to create a script that, when I pressed a certain keyboard key while hovering over a card in my on screen hand, it will play that card to a specific area on the table. Instead of pressing a key, will I be forced to instead create a button on the lower part of my screen near my on screen hand for each card? It's a shame the game doesn't include this feature automatically.
Watching these now to help me build a custom Cards Against Humanity clone for my D&D group to play on off weeks. It has helped me so much, so thank you! I am now struggling to handle the idea of auto-dealing 1 black card to the player on their turn start with turns enabled and onPlayerTurn() function. If I'm loading that script in the Global LUA scripting, I shouldn't have to attach it to an object since it's called on an event right?
I have no idea why, but int he moment I try to specify color, it doesn't deal the hand to anyone. amy I messing up the syntax or smth, it seems pretty clear that I just use it like "deck.deal(5, Green) or smth.deck.deal(5, "Green") doesn't work either.
If you have already found the decks from the GUIDs, then you can use putObject() to combine the decks. Something like: deck1.putObject(deck2) That would add deck1 into deck2. Not sure if that answers your question! api.tabletopsimulator.com/object/#putobject
@@LudoLodge Thank you very much for the reply. My script looks like this: ------------------------------------------------------------------------------------------------------------- LUA - Global: ------------------------------------------------------------------------------------------------------------- DECK1_GUID = "96212f" DECK2_GUID = "521917" ------------------------------------------------------------------------------------------------------------- Lua - Button Object: ------------------------------------------------------------------------------------------------------------- DECK1_GUID = Global.getVar('DECK1_GUID') DECK2_GUID = Global.getVar('DECK2_GUID')
function setUpCards() local deck = getObjectFromGUID(DECK1_GUID) deck.randomize() deck.deal(4) end ------------------------------------------------------------------------------------------------------------- UI - Button Object: ------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------- This shuffles card deck 1 and each player is dealt four cards. That's working. Now all that is missing is to put card deck 2 on card deck 1 and shuffle again. For this I need this: deck1.putObject (deck2). But where exactly do I have to write it in and what exactly do I have to write there? I think it should come after the following part: function setUpCards () local deck = getObjectFromGUID (DECK1_GUID) deck.randomize () deck.deal (4) DECK1_GUID.putObject (DECK2_GUID)
That doesn't work and I get an error message. I am very, very grateful for any further help.
@@guntherdillmann3340 Sorry for the late response, gets hard to keep track of all the comments across my videos these days! The main issue I see is with "DECK1_GUID.putObject (DECK2_GUID)". The "putObject()" function is for the deck itself, but "DECK1_GUID" is just a string (text) as opposed to the deck. You already used "getObjectFrom GUID()" above to get the deck from the GUID, so you should just need something like this: function setUpCards() local deck1 = getObjectFromGUID(DECK1_GUID) local deck2 = getObjectFromGUID(DECK2_GUID) deck1.randomize() deck.deal(4) deck1.putObject(deck2) deck1.randomize() Hope that helps!
Hello! quick question if i have a deck of cards that during set up need to be placed in some parts of the board. what function will you use so that they go directly to those snapping points?
A lot of this is definitely going to help. Just one question. Randomizing 3 different bags with tiles is no problem. However, I then need to put 18 tiles from Bag 1 into Bag 4, then 12 tiles from Bag 2 into Bag 4, and finally 6 tiles from Bag 3 into Bag 4 (and then randomize bag 4, which again, is no problem). What function is used to transfer a number of items between bags?
Your main friends here are going to be the "takeObject()" and "putObject()" functions. This is untested, but it might look something like this (assuming you already have the references to the bag objects, and they are all shuffled): -- Move an object from bagOne to bagFour 18 times for _ = 1, 18 do bagFour.putObject(bagOne.takeObject({})) end -- Move an object from bagTwo to bagFour 12 times for _ = 1, 12 do bagFour.putObject(bagTwo.takeObject({})) end -- Move an object from bagThree to bagFour 6 times for _ = 1, 6 do bagFour.putObject(bagThree.takeObject({})) end Hope that helps!
@@LudoLodge Exactly what I needed. Thank you so much. I was initially having issues because I already had bags 1-3 defined from local bag# = getObjectFromGUID and then using randomize on them. Bag 4 starts empty so I forgot to identify it before trying to use the putObject function on it.
I can't get the deck to shuffle. I get an error saying I'm trying to index a nil value. I have the exact same code as in the video before he adds dealing :(
And can you do this with a bag in which there are many different items? You see, I'm new to scripting, but I need to make sure that when the button is pressed, all the objects in the bag are distributed according to the specified parameters
Great teach. I had a specific trouble in my game I wanted to ask about. In my game you build your deck by shuffling three smaller decks. Every player has their own. There is a common mechanic in the game where players take the top card of their discard pile and put it on bottom of their deck. Is it possible to make a button that could automate that. It’s several steps with an object that is randomly generated depending on players
Definitely possible, just a question of what might be the best approach! I would have to play around with it myself to say for sure, but one way might be to change the deck's position to temporarily be slightly raised, and then move the top card of the discard pile underneath it (flipping it). I don't think Tabletop Simulator's API provides a method for adding a card to the bottom of a deck, so a manual approach like this might be necessary. Let me know if you find a solution that works for you!
@@LudoLodge i do know players can manually put cards on the bottom of a deck by holding, right-click, then slide under. but I have to see if that can be programmed.
Hi, Ryan. Thanks for all your video tutorials, I really appreciate all of them. I have a question for you. I want to deal the top card of a deck using a button and add it just to the player's hand who clicked the button. I'm sorry for the wierd request, I know it's way too easy doing it manually. Alessandro
Hey Alessandro, the function that you provide for when a button is clicked includes the color of the player that clicked it. Look here for more details: api.tabletopsimulator.com/object/#createbutton You should then be able to pass that color to the deal function to deal to that specific player: api.tabletopsimulator.com/object/#deal
@@LudoLodge Thank you, this was extremely helpful. This way I didn't need to use xml code to create the button like you use to do in your tutorials, since the createbutton() function itself do the job. I also noticed the parameters values (for example position, width and height), are quite different from each other button: setting the values you use for the xml button it creates a button way far away from the object the button is attached to. Looking forward to new scripting tutorials!
Great video, I tried to do the exact same script but having trouble with dealing cards. For some reasons if i'm not choosing a color the cards aren't deal but if i choose a color (black because it's the only i can get beside grey but this one is spectator) the cards are dealt but none are fliped on the table. Do you know how to solve this problem. I use the exact same script as shown in this video so i'm a bit confused, not really good at programming :s
why is "local deck = DECK_GUID" not enough? It looks like theres a global variable in the beginning of the script which is called "DECK_GUID", able to server as a container containing the string of the global variable defined in the global script.
So, suppose that I needed to do this with multiple decks on the same setup button. One deck deals out. One deck flips into a row. How could I differentiate the decks using the same startup button?
You would just need to get the GUID for each deck you want to deal from, and then reference those all in the same function that is tied to the "onClick" for the button. So in the "setUpCards()" function, you could just repeat what is there, but use a different GUID when getting the deck with "getObjectFromGUID()".
@@LudoLodge I think I figured out that when the cards are reassembled, they become a new deck, so I cannot reuse the code endlessly, as if say I was building a trick-taking game and wanted to reuse the button to deal each new round. Lots yet to learn.
@@iffixsantaph4267 Yeah this example is definitely simplified. One way around that may be using a scripting zone to get the GUID of the deck. That way, whatever deck happens to be in that scripting zone will be used, even if the GUID changes.
Good job, i'm enjoying your series on TTS and especially the scripting. As an ageing ex-COBOL programmer I sometimes struggle with this new fangled object based stuff :) I believe you can also create the button within the LUA code (using self?) rather than doing it in the UI. Is there a specific reason to do it in a particular way?
You are correct, you can create buttons via the Lua code, which is the original method that Tabletop Simulator provided. Separating it into the UI tab follows the commonly recommended design pattern of separating "view" and "controller" logic. The short answer is that it is simply a little easier to organize and maintain than if everything was in the Lua code. For some it will just come down to personal preference. Glad you have enjoyed the videos so far!
For some reason my checker button was inverse, so the button (label) didn't work. It took me ages to find out I actually had to flip the checker button before the button worked. Scripting can be very frustrating.
Thanks for the video. I am struggling with getting a basic script working. I have tried to copy your code from this video straight into a test module, but it keeps giving me issues like text that is backwards on the button, and errors that I am not loading a script. Can you save a basic working version of this to the Workshop so I can download it and see if the issue is my setup? Thanks.
Hi Kevin, the backwards text is probably due to the checker object being upside-down, you should be able to grab it and press 'F' to flip if. As for other errors, I'd need to know what the error is saying... Not a bad idea for me to add the examples from these videos to the workshop though.
Width and height are in the hundreds. Blots out my table. How scaled up is your own table? I mean this is helpful but wow I had to input smaller sizes. NOPE that's not what's happening, I'm just getting a massive white panel when I try this. Help?
Hi. That's a pretty good intro (series). Thanks! I tried to replay this in my game and encounter the following problem: I have a deck of cards (22) and a button (attached to a checker) which should reveal the topmost card. I chose deck.takeObject like in your code. However, when there's only 1 card left on the pile, the script errors out because `deck = getObjectFromGUID(CARDS_EVENTS)` returns nil. Do you face the same issue? And why is that and how can I get around it? As said: there is still one card left and I can't reveal it. Any help appreciated. Thanks in advance
Hello I started watching your videos to try to program a simple card game like UNO in tabletop simulator, until I could get to fully program monopoly. But you do not explain how to combine the button to deal cards using the "scripting zone", in case the deck moves from place and only explained the "scripting zone" commanding it from the chat (which also did not work for me and I have exactly the same code as you, and the chat gives me back that the variable is not valid) As well as how to combine the "scripting zone" to deliver a card in any place indicated on the table and in turn to deal to all players the amount of cards needed for the game. Conclusion I would be interested that you do some more videos explaining how to program more games or single things and then join everything to work together, I hope it is within your interests to continue making videos of this type since long ago you did not upload anything more about tabletop simulator.
You should be able to test how well it works with multiple seats by using the Hot Seat mode instead of the Single Player mode when setting up the room
Thanks for the tip!
I was about to write this.
For the record. Y is always up and down.@@LudoLodge i know there is a lot of people who get their axies wrong.
EDIT: I was using the exact same code as the tutorial during Add Setup Button section and getting nowhere; I later found out that my checker was flipped down, submerging my button into the table. Ludo Lodge helped me in surprising time. I love this channel.
I may be able to help if you paste your code here and describe what results you are getting.
@@LudoLodge
Set Up Cards
The button doesn't appear at all. I first discovered I had typed it into Lua, which is a rookie mistake, but my first time. But now that I've put it into UI, I'm still not getting anything.
(Eyes rolling) So, apparently it dropped my checker upside down. So when I loaded it, the text for the button disappeared. You do excellent work.
@@iffixsantaph4267 I've made that same mistake! One of many little "gotchas" when using TTS.
@@LudoLodge I'm going to be watching your videos a lot. I have a lot of games to upload to TTS, so I'm looking forward to learning what I can.
I apologise for commenting on an older video but you're the only one who's been able to help me so far! This video got me setting up some card setup in my own mod very easily, but what I'm struggling with is doing the same for some custom Tokens as well. I just can't figure out how to correctly adjust the script to have it do the same thing, move Tokens to specific locations at the press of a button. Looking up answers online tends to find only half the answer, assuming you're already rather well versed in lua and sadly I'm totally new as of this week! Having been able to work this video out easily enough, I can't imagine it's that much harder to have the process work for Tokens as well. I was hoping a genius here might be able to give me some tips!
Excellent explanation. With my limited coding knowledge, I was able to follow along and understand what you're explaining without going back multiple times.
These are SO helpful. I just started working on putting a few of my prototype games into TTS. These scripting tutorials are making my life so much easier. Thank you.
You taught this very well. I have no coding experience but I feel confident I can do this. Thank you.
The comma between true and position is very important lol, learnt that the hard way.
Hey! Big props for including timestamps in your vid, this is extremely helpful. Especially thankful that you explain your reasoning for stuff but don't slow down your pacing by babying people who don't know basic coding ideas. Some people won't like that but I really appreciate it
I do have programming experience with Microsoft VBA and SQL but even so I feel that the scripting explanations given here are clear and simple enough for a complete beginner to use. Also it helps that the vocal performance is measured and delivered at a pace that makes it very easy to listen to. Having developed a card game using Microsoft Access previously, some of the syntax of the Lua language is very recognisable. Great work and I look forward to watching more.
Glad you found it helpful, Ralph! It is very true that every programming language you learn only makes it easier to pick up more in the future!
it should be noted that placing the checker on the table does not create its button in the scripting. it is created by clicking rmb/scripting/scripting editor, then it appears. but it will disappear if there is nothing written in that window.
Thanks so much! I got so much to learn so diving in with tts and this series.
Thank you for the guide. Is there a video of you who teaches how to restart the game or begin another round with all cards and objects go back to first position?
perfect timing to upload this series. I just started learning a bit of LUA to script stuff in TTS . Gotta get my Information from so many sources, your Videos will be on of these sources and will help me a lot. I did all my buttons with LUA only, but XML seems to be a bit less messy in that regard, so I'm gonna try that too at some point. For now I want to stay with LUA.
This is so good! Thank you so much. Would you consider doing a video about cleaning up? For instance, say there are two different decks, and we need to gather all the cards of one type from the table and hands, and the other type of cards from the whole area or a discard pile.
That is a great suggestion! Added to the list. :)
This was fantastic. Thanks so much for these videos!
Suggestion: If you destroy the button, the script is also destroyed and I've found that breaks my connection to VSCode and I can no longer edit that script. So, leave that out until it works as expected and add at the end.
With this and your other videos, I was able to create setup scripts for two mods and a next turn setup for a 2nd mod.
Clear, comprehensive, and personable!
I tried both the button and dealing a card and it was the most satisfying accomplishment in long time. You are an excellent instructor. Q: Is it possible to script a card to retain unique attributes regardless if it is in a deck or a single card? I'm going to be scripting zones next. Thank you.
Very good tutorial! Love Lua - it's so simple
Whoa, whoa. You had me until arrays start at 1.
But seriously, thanks for the video tutorials on this application. Simple and comprehensive.
Haha I had the same reaction when I was starting to learn the Lua syntax.
I actually like the implementation you did for laying out cards in the video better than the one you gave in the overlay more in general. Say I want to lay cards/tiles over a board. The step taken from the deck to the first spot will likely be one distance, and the subsequent steps to lay out over spaces will be a different regularly repeated distance.
If that was the case, you could have the formula look something like deckPos[1] + 5 + (i * 3). The main point is that incrementing xPos is a little redundant since the i counter variable is already incrementing, but it works either way.
Is there a way to add in a sorting function in the deal script? something that sorts the cards in a defined order once in hand?
Darn, you're a good teacher. Thanks so much!
What is the ''unit'' that you went with ''1 + 3''? is it width of a card or is it what tts perceives to be an inch or a centimeter or something? or maybe some in game unit of measurement
Thanks for the great video, Ryan. Awesome job explaining as always.
This is extremely helpful. Thank you very much for making this!
Late to the party here, but this was very informative and helpful into setting up some neat loops and object code orientation.
Great Tutorial! Thanks!, now i can automate setup process on my prototype which have a couple of decks and some are being dealt to the players and some are dealt to the row on the board.
I have 2 questions:
1. Is there any way to automatically snap cards dealt to the row to a snap point ?
2. Lets say i have a bag object with various tiles, at the start of the game i want to place them on the board in specific places (using snap points)
Thanks and keep up this great work ! :)
Where was this like two weeks ago!? Lol. Nice work, very useful!
Great video! I am trying to make a script to shuffle 24 card deck and then lay them out in a 4x6 grid (4 rows 6 columns). Is that possible with 1 click button, and if so how is that done?
Thanks for posting the code to GITHUB, and the other video on using onCHAT to test stuff out. I am trying to understand the WAIT function but the API is overwhelming me. I simply want to deal 3 cards to a zone that has an existing starting card - WAIT 3-5 seconds for the cards to get there, and then SHUFFLE them. Can you provide a working example of Wait that allows the PutObject command to finish? Thanks!
The Wait static class looks like it has several options for delaying the execution of code. For your use case, it sounds like you want to use Wait.time to specify a number of seconds. This would end up looking something like this:
Wait.time(myFunction, 3)
In this case, after 3 seconds, it will run the code in your function named "myFunction". So you could have a function named something like "shuffleDecks", and then use Wait.time(shuffleDecks, 3) after the code for dealing to the zones.
is there a way to script, once you took a card from the table, it will draw the next card that needs to be there?
is it possible to script a sound to play when a specific card is drawn?
Thanks a lot! my TSS mod gets better with every video ;) I especially like that you already use good coding practice before it is even necessary, I know I would make mistakes everytime with changing GUIDs.
Just what I was looking for, thanks!
My code is identical to yours but I get an error that reads "Unexpected symbol near "Deck"
I really appreciate your videos. I do need your help however.
Using your script, I made a button that deals 4 cards and another that draws 1 card. I want the draw card to draw a card ONLY for the player that clicks it. The issue is that every single player receives the drawn card and not just the person who pressed the button. Is there a way to adjust this?
Suppose I wanted to add scripting to a card. What functions does the card have inherently? Does a card lose its sense of self when it's put into a deck? (Will it lose its code in such a case?)
Thanks so much for this! It also worked taking tiles out of a bag and laying them out. Any advice on dealing a second row without having to make another button?
Ended up trying a loop within a loop for the number of rows and it worked!
Exactly what I was going to suggest, nice work! :)
Thanks I'm completely new to scripting and these are really super helpful. would it be possible to set cards out like this to players depending on how many players are seated at the table. So that only players seated at the table would get cards into their hand and some out in front of them individually?
Thanks for the great tutorials! I was wondering though if it's possible to tell a button to take a specific card from the deck (or a specific object from inside another). For example, when the button is pressed I want the ace of spades to be taken from the deck and laid on the table.
You should be able to! The takeObject() method has optional parameters for either and index or GUID for the object to be taken: api.tabletopsimulator.com/object/#takeobject. As long as you have GUID of the card you want, you should be able to use that parameter to grab it specifically.
I have a grid of snap points that I've set to the same tag as the cards in a deck. They aren't the only snap points on the table but they are the only ones I want to use for that deck. Is it possible to pull the positions of those snap points so that when I run my script it places one card on each snap point? I found a getSnapPoints function but I don't know how to use it to do what I need, or if it's even possible.
It looks like "getSnapPoints()" will return a table of all the snap points (if you call it on Global), where each snap point is represented by another table that has some properties including tags: api.tabletopsimulator.com/object/#getsnappoints
So it seems to me you might be able to do something like this (untested):
local snapPoints = Global.getSnapPoints()
-- Loop over each snap point
for _, snapPoint in ipairs(snapPoints) do
-- Loop over each tag on the snap point
for _, tag in snapPoint.tags do
-- If the tag matches our card tag, then take the card and put it at the snap point's position
if tag == cardTag then
deck.takeObject({flip=true, position=snapPoint.position})
end
end
end
Hope that helps!
What if I wanted the number of cards to go down based on the number of players?
I am not sure how I would write that out in the scripting. I feel like I would have to let TTS know that if there are 3 players, then draw 3 cards, but if there are 4 players, then draw 2 cards. Not sure how to do that though.
How would you change this if you wanted a button that was used to draw cards based on empty spaces on the field? For context I have a store in my game. I want to create a button that will draw and place cards only in spots that have an empty space because a player has bought 1 or more cards from the store.
Never mind I see your next video will probably answer this question :)
So i followed through woth making the button its self. And everything matches. But the button is streched across the table in lenght. But width and hight is right
I want to create a script that, when I pressed a certain keyboard key while hovering over a card in my on screen hand, it will play that card to a specific area on the table. Instead of pressing a key, will I be forced to instead create a button on the lower part of my screen near my on screen hand for each card? It's a shame the game doesn't include this feature automatically.
Watching these now to help me build a custom Cards Against Humanity clone for my D&D group to play on off weeks. It has helped me so much, so thank you! I am now struggling to handle the idea of auto-dealing 1 black card to the player on their turn start with turns enabled and onPlayerTurn() function. If I'm loading that script in the Global LUA scripting, I shouldn't have to attach it to an object since it's called on an event right?
I have no idea why, but int he moment I try to specify color, it doesn't deal the hand to anyone. amy I messing up the syntax or smth, it seems pretty clear that I just use it like "deck.deal(5, Green) or smth.deck.deal(5, "Green") doesn't work either.
Are the units for space in inches? In this case it is 3*i _what_ exactly? Thanks 😁
I'm not actually sure... I usually just play with the numbers until things look right. :P
The script is great. I copied it and it works fine.
How does the script work when I have 2 decks of cards off the table
want to mix together?
If you have already found the decks from the GUIDs, then you can use putObject() to combine the decks. Something like:
deck1.putObject(deck2)
That would add deck1 into deck2. Not sure if that answers your question!
api.tabletopsimulator.com/object/#putobject
@@LudoLodge Thank you very much for the reply.
My script looks like this:
-------------------------------------------------------------------------------------------------------------
LUA - Global:
-------------------------------------------------------------------------------------------------------------
DECK1_GUID = "96212f"
DECK2_GUID = "521917"
-------------------------------------------------------------------------------------------------------------
Lua - Button Object:
-------------------------------------------------------------------------------------------------------------
DECK1_GUID = Global.getVar('DECK1_GUID')
DECK2_GUID = Global.getVar('DECK2_GUID')
function setUpCards()
local deck = getObjectFromGUID(DECK1_GUID)
deck.randomize()
deck.deal(4)
end
-------------------------------------------------------------------------------------------------------------
UI - Button Object:
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
This shuffles card deck 1 and each player is dealt four cards. That's working.
Now all that is missing is to put card deck 2 on card deck 1 and shuffle again.
For this I need this: deck1.putObject (deck2).
But where exactly do I have to write it in and what exactly do I have to write there?
I think it should come after the following part:
function setUpCards ()
local deck = getObjectFromGUID (DECK1_GUID)
deck.randomize ()
deck.deal (4)
DECK1_GUID.putObject (DECK2_GUID)
That doesn't work and I get an error message.
I am very, very grateful for any further help.
@@guntherdillmann3340 Sorry for the late response, gets hard to keep track of all the comments across my videos these days!
The main issue I see is with "DECK1_GUID.putObject (DECK2_GUID)". The "putObject()" function is for the deck itself, but "DECK1_GUID" is just a string (text) as opposed to the deck. You already used "getObjectFrom GUID()" above to get the deck from the GUID, so you should just need something like this:
function setUpCards()
local deck1 = getObjectFromGUID(DECK1_GUID)
local deck2 = getObjectFromGUID(DECK2_GUID)
deck1.randomize()
deck.deal(4)
deck1.putObject(deck2)
deck1.randomize()
Hope that helps!
Hello! quick question if i have a deck of cards that during set up need to be placed in some parts of the board. what function will you use so that they go directly to those snapping points?
Big thanks Ryan, very helpful
When I try to create a button, TTS always tells me "name cannot start with the ' ' character". Can any one tell me what I do wrong?
A lot of this is definitely going to help. Just one question.
Randomizing 3 different bags with tiles is no problem. However, I then need to put 18 tiles from Bag 1 into Bag 4, then 12 tiles from Bag 2 into Bag 4, and finally 6 tiles from Bag 3 into Bag 4 (and then randomize bag 4, which again, is no problem). What function is used to transfer a number of items between bags?
Your main friends here are going to be the "takeObject()" and "putObject()" functions. This is untested, but it might look something like this (assuming you already have the references to the bag objects, and they are all shuffled):
-- Move an object from bagOne to bagFour 18 times
for _ = 1, 18 do
bagFour.putObject(bagOne.takeObject({}))
end
-- Move an object from bagTwo to bagFour 12 times
for _ = 1, 12 do
bagFour.putObject(bagTwo.takeObject({}))
end
-- Move an object from bagThree to bagFour 6 times
for _ = 1, 6 do
bagFour.putObject(bagThree.takeObject({}))
end
Hope that helps!
@@LudoLodge Exactly what I needed. Thank you so much. I was initially having issues because I already had bags 1-3 defined from local bag# = getObjectFromGUID and then using randomize on them. Bag 4 starts empty so I forgot to identify it before trying to use the putObject function on it.
I can't get the deck to shuffle. I get an error saying I'm trying to index a nil value. I have the exact same code as in the video before he adds dealing :(
If you post your code, I might be able to spot the error. 👀
Did you ever figure this out? I'm seeing the same thing. Working until it's shuffle time with the same error
And can you do this with a bag in which there are many different items?
You see, I'm new to scripting, but I need to make sure that when the button is pressed, all the objects in the bag are distributed according to the specified parameters
Really helpful tutorial, thanks.
Great teach. I had a specific trouble in my game I wanted to ask about. In my game you build your deck by shuffling three smaller decks. Every player has their own. There is a common mechanic in the game where players take the top card of their discard pile and put it on bottom of their deck. Is it possible to make a button that could automate that. It’s several steps with an object that is randomly generated depending on players
Definitely possible, just a question of what might be the best approach!
I would have to play around with it myself to say for sure, but one way might be to change the deck's position to temporarily be slightly raised, and then move the top card of the discard pile underneath it (flipping it). I don't think Tabletop Simulator's API provides a method for adding a card to the bottom of a deck, so a manual approach like this might be necessary.
Let me know if you find a solution that works for you!
@@LudoLodge i do know players can manually put cards on the bottom of a deck by holding, right-click, then slide under. but I have to see if that can be programmed.
Hi, Ryan. Thanks for all your video tutorials, I really appreciate all of them. I have a question for you. I want to deal the top card of a deck using a button and add it just to the player's hand who clicked the button. I'm sorry for the wierd request, I know it's way too easy doing it manually.
Alessandro
Hey Alessandro, the function that you provide for when a button is clicked includes the color of the player that clicked it. Look here for more details: api.tabletopsimulator.com/object/#createbutton
You should then be able to pass that color to the deal function to deal to that specific player: api.tabletopsimulator.com/object/#deal
@@LudoLodge Thank you, this was extremely helpful. This way I didn't need to use xml code to create the button like you use to do in your tutorials, since the createbutton() function itself do the job. I also noticed the parameters values (for example position, width and height), are quite different from each other button: setting the values you use for the xml button it creates a button way far away from the object the button is attached to. Looking forward to new scripting tutorials!
Great video, I tried to do the exact same script but having trouble with dealing cards. For some reasons if i'm not choosing a color the cards aren't deal but if i choose a color (black because it's the only i can get beside grey but this one is spectator) the cards are dealt but none are fliped on the table. Do you know how to solve this problem. I use the exact same script as shown in this video so i'm a bit confused, not really good at programming :s
why is "local deck = DECK_GUID" not enough? It looks like theres a global variable in the beginning of the script which is called "DECK_GUID", able to server as a container containing the string of the global variable defined in the global script.
Great stuff man, much appreciated!
So, suppose that I needed to do this with multiple decks on the same setup button. One deck deals out. One deck flips into a row. How could I differentiate the decks using the same startup button?
You would just need to get the GUID for each deck you want to deal from, and then reference those all in the same function that is tied to the "onClick" for the button. So in the "setUpCards()" function, you could just repeat what is there, but use a different GUID when getting the deck with "getObjectFromGUID()".
@@LudoLodge I think I figured out that when the cards are reassembled, they become a new deck, so I cannot reuse the code endlessly, as if say I was building a trick-taking game and wanted to reuse the button to deal each new round. Lots yet to learn.
@@iffixsantaph4267 Yeah this example is definitely simplified. One way around that may be using a scripting zone to get the GUID of the deck. That way, whatever deck happens to be in that scripting zone will be used, even if the GUID changes.
Good job, i'm enjoying your series on TTS and especially the scripting. As an ageing ex-COBOL programmer I sometimes struggle with this new fangled object based stuff :)
I believe you can also create the button within the LUA code (using self?) rather than doing it in the UI. Is there a specific reason to do it in a particular way?
You are correct, you can create buttons via the Lua code, which is the original method that Tabletop Simulator provided. Separating it into the UI tab follows the commonly recommended design pattern of separating "view" and "controller" logic. The short answer is that it is simply a little easier to organize and maintain than if everything was in the Lua code. For some it will just come down to personal preference.
Glad you have enjoyed the videos so far!
For some reason my checker button was inverse, so the button (label) didn't work. It took me ages to find out I actually had to flip the checker button before the button worked. Scripting can be very frustrating.
Great tutorial
i used the same code in the video, but the checker appeared on top of the button, how could I fix it, thank you
Hi! You might just need to flip the checker over, trying picking it up and then hitting the 'F' key.
Thanks for the video.
Thanks for the video. I am struggling with getting a basic script working. I have tried to copy your code from this video straight into a test module, but it keeps giving me issues like text that is backwards on the button, and errors that I am not loading a script. Can you save a basic working version of this to the Workshop so I can download it and see if the issue is my setup? Thanks.
Hi Kevin, the backwards text is probably due to the checker object being upside-down, you should be able to grab it and press 'F' to flip if.
As for other errors, I'd need to know what the error is saying... Not a bad idea for me to add the examples from these videos to the workshop though.
Width and height are in the hundreds. Blots out my table.
How scaled up is your own table? I mean this is helpful but wow I had to input smaller sizes. NOPE that's not what's happening, I'm just getting a massive white panel when I try this. Help?
Hi. That's a pretty good intro (series). Thanks!
I tried to replay this in my game and encounter the following problem:
I have a deck of cards (22) and a button (attached to a checker) which should reveal the topmost card. I chose deck.takeObject like in your code. However, when there's only 1 card left on the pile, the script errors out because `deck = getObjectFromGUID(CARDS_EVENTS)` returns nil. Do you face the same issue? And why is that and how can I get around it? As said: there is still one card left and I can't reveal it.
Any help appreciated.
Thanks in advance
Hi! I actually discuss this specific issue in this video: ruclips.net/video/wuh5VbDE8Zc/видео.html
Let me know if you end up still having questions!
thanks for guides
Thanks so much.
now this is a tutorial
Hello I started watching your videos to try to program a simple card game like UNO in tabletop simulator, until I could get to fully program monopoly. But you do not explain how to combine the button to deal cards using the "scripting zone", in case the deck moves from place and only explained the "scripting zone" commanding it from the chat (which also did not work for me and I have exactly the same code as you, and the chat gives me back that the variable is not valid) As well as how to combine the "scripting zone" to deliver a card in any place indicated on the table and in turn to deal to all players the amount of cards needed for the game. Conclusion I would be interested that you do some more videos explaining how to program more games or single things and then join everything to work together, I hope it is within your interests to continue making videos of this type since long ago you did not upload anything more about tabletop simulator.
i keep getting a attempt to call nil value
oh nvm i found what i did wrong lol
Set Up Cards Butt
"I don't have a way to simulate more players". Yes you do. Start a hotseat game.
Am I the only one staring at a broke screen?...