ID:2591456
 
(See the best response by Kaiochao.)
I recently started playing with DM and I'm starting to get a hang of a few things. After reading through the Blue Book and running through a few tutorial exercises I'm able to do some basic things on my own but there is still so much that is overwhelming. No matter how many times I read through I can't form an understanding of the usage of many things.

The last challenge I gave myself was to design a shopkeeper NPC with a buy verb associated that would open up a window listing the items for sale and their price. I tried quite a few different approaches but alas, I was lost. I did some digging and what luck! I found Lummox JR's "Learn to Love Associative Lists" tutorial. This was exactly what I was looking for! I read through the section on shopkeepers and I was lost. I entered the code into DM hoping to grasp a basic understanding of how the code works. Some of it I understood, much of it I did not.

I've come to the conclusion that I need to step back a bit and try something simpler but I don't really know where to go from here. I was wondering if anyone could suggest some simple (preferably RPG themed) challenges to give myself or list some references that might be useful for someone with absolutely no programming experience. For a frame of reference of my current understanding I've completed Zilal's RPG tutorial (http://www.byond.com/forum/post/36143) and have a good understanding everything within that and can recreate and build off some of it.

Maybe it'd be easier to go through the tutorial you had an issue with. What parts of the shopkeeper code from that column didn't make sense?
In response to Lummox JR
Okay, I didn't think I had a good enough understanding as a whole but I'm certainly willing to try that.

mob/shopkeeper/apothecary
New()
contents=newlist(/obj/potion/heal,
/obj/potion/confusion,
/obj/potion/poison)

verb/buy()
set src in oview(1)
var/list/choices = new

I don't think I exactly understand the use of new. The rest makes sense. Is new creating new objects or the list itself? I think it's creating the list itself because new is used again later in the code when we successfully buy an item but I still don't quite understand why.

    var/obj/O
for(O in contents)
choices += O
var/item = input(usr, "What do you want to buy?","Buy","Nevermind") \
as null|anything in choices

When I run this code and interact with the shopkeeper "What do you want to buy?" is displayed but "Buy" and "Nevermind" are not.

I also don't understand the use of "as null|anything in choices"

    if(!item) return
O = item // the user selected an item
if(usr.gold < O.price)
usr << "You don't have $[O.price] to pay for \a [O]!"
return
usr.gold -= O.price
O=new O.type(usr) // create a new object of this type
usr << "You pay $[O.price] for \a [O]."


This last bit I believe I understand. Other than the use of "return". I was under the impression it was used to return a value but that doesn't appear to be the case here. Is \a used to call "anything in choices"?
In response to Bokoa
Best response
Always check the built-in reference for built-in things. You can open it in Dream Maker with F1.
If you click on something in the code and hit F1, it will try to open to that page.
The reference is everything. It has the most up-to-date documentation on all built-in things.

Things for you to look up:
* newlist proc - it's just shorthand, really
* new proc
* input proc - the tutorial code says to default to an option called "Nevermind" but that isn't actually an option, so the code must be wrong
* return statement - you're right, it does return a value, but more importantly it ends the proc by returning execution back to the caller (along with the value)
* macros (text) - this is for the \a contextual macro

I think the reference should be able to answer all of the questions so far, but if you have any more, feel free to ask.

Challenge: read through the whole thing. (It's actually not a lot compared to any of the bigger engines out there.)

Exercises: make little tech demos for everything.
In response to Kaiochao
To be honest I've been using the reference religiously, haha. The problem is I've been having some trouble understanding some of the descriptions. That's what I meant when I said I've encountered some things that have been overwhelming me. I never considered reading through the entire thing, I think that's a great suggestion. Thank you, I really appreciate that.

I'm not sure I know what you mean by making tech demos for everything. Are you suggesting I should write a piece of code that implements each part of the reference to gain a better understanding?
In response to Bokoa
The reference is hard to understand at times. In addition to this forum, there are Discord servers where you can ask questions and get answers pretty quick.

And yeah, that's what I'm talking about. Demonstrating your understanding through your own projects, figuring things out as you go, seeing things in action. That's probably what you're already doing, though. You probably wouldn't be here if you didn't already have some kind of game to develop.
In response to Kaiochao
Thanks for the tip on the discord server, I wasn't aware of that. I think you've given me a great place to continue on from with reading through the reference. I was indeed writing some demos to grasp concepts, I think I just got a bit ahead of myself. I do have an idea, and I think it's somewhat unique but I have no intention of trying to tackle it yet XD. For now I'm just trying to focus on some of the fundamentals.

For anyone else in my situation with little to no experience, reading through the reference was an excellent suggestion. You'll come to find there are tons of built in things that many of the guides don't get a chance to go over. I've only gone over a small portion so far but it's already given me a few ideas on how I can handle some things differently.
In response to Bokoa
Bokoa wrote:
mob/shopkeeper/apothecary
New()
contents=newlist(/obj/potion/heal,
/obj/potion/confusion,
/obj/potion/poison)

verb/buy()
set src in oview(1)
var/list/choices = new

I don't think I exactly understand the use of new. The rest makes sense. Is new creating new objects or the list itself? I think it's creating the list itself because new is used again later in the code when we successfully buy an item but I still don't quite understand why.

Part of the confusion is that I think you might be conflating new and New. The language is case-sensitive so these are different things.

new() is an instruction to create a new object. In the code above it doesn't have any parentheses, because BYOND understands that var/list/choices = new means var/list/choices = new/list().

New() with a capital N is a proc that runs when an object is created. In this example, let's say this apothecary mob is on your map. When the world begins, the map objects are all created, so the shopkeeper's New() proc will run then.

As for newlist(), that's sort of a shorthand in the compiler to create a list of objects from their type paths. newlist(/obj/A, /obj/B) is the same as list(new/obj/A, new/obj/B).

    var/obj/O
for(O in contents)
choices += O
var/item = input(usr, "What do you want to buy?","Buy","Nevermind") \
as null|anything in choices

When I run this code and interact with the shopkeeper "What do you want to buy?" is displayed but "Buy" and "Nevermind" are not.

You know, the "Nevermind" is actually a mistake in my code! That's where the default value would go, but there's no default value used here. For the life of me I don't know why I put that there.

The "Buy" text however should show up as the title of the input popup.

I also don't understand the use of "as null|anything in choices"

This tells input() that the options it should display need to come from the choices list we just created.

The "as null|anything" tells the input what kinds of responses are allowed. For instance, if you have "as obj" for one of a verb's arguments, that verb can only take objs for that argument. "anything" here means any value in the list is acceptable. "null" means that the input can be canceled, which will send back null as a result. The combination of the two (with the | operator) tells Dream Seeker that you can choose any item in the list, but you should also be given an option to cancel.

    if(!item) return
O = item // the user selected an item
if(usr.gold < O.price)
usr << "You don't have $[O.price] to pay for \a [O]!"
return
usr.gold -= O.price
O=new O.type(usr) // create a new object of this type
usr << "You pay $[O.price] for \a [O]."

This last bit I believe I understand. Other than the use of "return". I was under the impression it was used to return a value but that doesn't appear to be the case here. Is \a used to call "anything in choices"?

The return statement can either return a value from a proc, or simply end the proc. If you just use the return statement without a value, the default return value (the . var) is returned.

The \a in the text is a macro that looks at the object that follows, and prints out "a", "an", or "some" depending on the object. (You get "some" if the object's gender is set to "plural", which you might do for gold or food or whatnot.) Obviously the \a macro isn't 100% foolproof since there are English words that begin with vowel sounds but not vowels, or vowels but not vowel sounds, but it's good enough most of the time to figure out whether you want "a" or "an".

Also take a look at the \s macro. That adds an "s" into the text if there was a number other than 1 before it.

usr << "You have [amount] coin\s."
Bokoa wrote:
I've come to the conclusion that I need to step back a bit and try something simpler but I don't really know where to go from here.

I was wondering if anyone could suggest some simple (preferably RPG themed) challenges to give myself or list some references that might be useful for someone with absolutely no programming experience. For a frame of reference of my current understanding I've completed Zilal's RPG tutorial

If you want to take a step back, I recommend taking a step back from the RPG genre. I'm not saying you should abandon it, but "simple" and "RPG themed" don't really go together all the time. Just be careful about launching into "THE role playing game," you know that one you keep fantasizing about and have written out pages of items and abilities and stats and world maps? Well most of us have tried to start that and realized, as you said, that 'there is still so much that is overwhelming.'

You're on the right track by taking things one task at a time. If you just do exercises forever though, you might get frustrated with having too much practice and not enough play. Try thinking of a really simple game that you can create using the skills you already have. Working on that will help you learn other skills apart from basic programming, including how to manage your code from a project-wide perspective. This might sound esoteric but it can be really easy to add a feature to your game, then realize later that the way you programmed it makes it very annoying or difficult to implement something else. Anyway, just saying you can make playable games without advanced DM knowledge.

As far as "RPG themed" exercises, here's what comes to mind for me:

- Create a level up system. Sounds obvious but you need some variable for the player to increase, then a way to determine if they have reached a certain threshold and give a reward. For example, you could have the player collect coins for "xp". After 20 coins, 60, 120, 200, etc you gain a level. Each level you can choose to increase your walking speed, digging power (to break walls for more coins), or jumping distance (to get over terrain for more coins). Already sounds like a game eh?

- Create an inventory system. A shopkeeper is nice and all but you need an inventory first! You should be able to pick up and drop items, have a limit on the number of items carried, and of course display them to the player.

- Create a saving and loading system. Almost all games benefit from being able to save data for the next time the program is run. In the coin-game example above, you would have to save the player's position, how many coins they have, what upgrade choices they have made, and keep track of which objects on the map need to be removed so the player can't collect the same ones over again.