Files
hpr-knowledge-base/hpr_transcripts/hpr2713.txt

147 lines
14 KiB
Plaintext
Raw Normal View History

Episode: 2713
Title: HPR2713: Resources in 4x game
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2713/hpr2713.mp3
Transcribed: 2025-10-19 08:00:50
---
This is an HPR episode 2,713 entitled Resources in Forex Game.
It is hosted by Tuku Toroto and is about 21 minutes long and carries a clean flag.
The summary is one way to implement meta types for all resources in Haskell.
This episode of HPR is brought to you by archive.org.
Support universal access to all knowledge by heading over to archive.org, forward slash donate.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Support universal access to all knowledge by heading over to archive.org.
Hello listeners, I'm Tuku and you are listening with the Hacker Public Radio.
Today I'm going to talk about a little bit how to one way of implementing resources in a Forex game written in Haskell.
And by resources I need raw resources like oil or gold or stone and not resources as I image and sounds.
So when I started with that it sounded pretty simple but it caught pretty tangled in the end.
And I'm not even doing a simple model. I'm writing this with my six year old kid.
They have lots of ideas about how to how the game should work and what kind of things this would add in.
And one of the things to us that it has to have tons of different kinds of resources like oil, gold, silver, iron, plastic, wood, different kinds of stones.
Stones I said already. But I wanted something simple that I can code before I retire.
And I was briefly considering a trading system decided against it at this point.
So the trading isn't going to be in the crowd part of the resource management.
And that this one at least.
So there's going to be three different kinds of resources, biological, mechanical and chemical.
So this is a very high level of fraction.
And three is a nice amount.
I think gives you enough of things to manage without getting too detailed.
And maybe I'm going to add extra big ones later.
This would be produced in few planets and needed for special purposes.
It might be a terrible but that would mean that I have to implement trading and diplomacy at the point when I'm doing that.
So that part is all in there.
And the main thing here was that I wanted more or less a tight safe system.
So not accidentally mids and resources and the code and not accidentally mixing the usage.
Like if you have a biological resources reserved for an if you have an amp, but that there is that these are biological resources.
You don't accidentally mix that with say chemical resources and if you are info that says that this is how long.
This is how much the project cost you don't accidentally mix it with the info that there's how much you actually have.
And the island is still not to be too tedious to code.
So something simple, flexible and type safe enough.
First of all, it's a good plan to have a look at the show notes.
I have to tell these things out there in detail, but the raw resource is a new type.
And basically it reaches a new type.
Roger resource are equals resource pattern open under one resource double colon in pattern closed.
But this means that the raw resources something that is represented as an index and it has a type type parameter on the left side of the equation on the.
Time constructor side, but that type parameter is in use on the right side on the value of constructor constructor.
This is a random type.
So when you are declaring a type of a raw resource saying that something is a raw resource, you have to specify what kind of raw resource it is.
But when you are using it in the code, you don't have to specify when you're creating a new raw resource.
You don't specify what type of it is compiler will infer for you what type you need in that specific context.
And it will give track that you don't accidentally mix them.
And this means that I achieve type safety and I don't have to type out the kind of raw resource handling all the time.
And then there are three types that represent resource types.
These are data biological equals biological and data mechanical equals mechanical and data chemical equals chemical.
These are just simple types that have one value.
So for example, if I define that I have a hundred units of biological resource and for example harvest.
And this first I have to tell the pipe is harvest double colon raw resource biological.
And then the actual assignment harvest equals raw resource one hundred.
And I'm fairly happy with this system.
It is pretty common case that I have to treat the raw resources as numbers.
It makes like I have to act together, subtract them from each other.
Like if if a farmer is collecting a harvest after year after year they just keep summing those.
And if somebody is eating the produce, produce the harvest you just subtract them and want that they are eating.
So I need numbers.
And I don't want to construct and on a test track take apart the raw resource in the data all the time.
So I define a type type class instance.
There's a type class number that defines common operations.
Like addition, subtraction, multiple cases taking the absolute value.
Taking the is the is the number positive or negative and creating a new numbers from the in the classes of the index.
Oh, numbers that are.
And this is a again I'm spelling this out in the show notes.
But it's basically just defining that the instance name raw resource D there.
And then the definition of each of the each of the functions that I mentioned the second ago.
And here when I'm defining the instance, I'm using the raw resource D because the raw resource takes a one type parameter.
But again, I'm no way telling what this D is in the implementation of those functions.
This means that these functions work with any any raw resource regardless of the pipe of raw resource.
If it's biological mechanical chemical, but these will take care that the each raw resource being summed, subtracted out of the same pipe.
So I can add to the raw resources to get the last sign and the compiler will make sure that they are off the correct pipe.
And this is this is this is what I like that it's detected on the compilation panel and not to run them.
Another thing that I need to do is comparing them like the equality we already have that can be automatically derived when defining the raw resource.
But yeah, smaller things sometimes important.
So again, this is a type class or that I'm going to get read instance which is very rich instance or inside parents raw resource D there.
And then there's only the implementation for the smaller or equal to function that deconstruct raw resource.
For raw resources given that's a parameter to it and compares the integral values.
And defining one function is enough because then the greater than and greater than and equal are defined in terms of this one and the equals function that I have already defined.
So I don't have to define more than one function.
In some cases in because of some specific optimization one could define the rest of the functions in the same manner but in this case I don't see need for that.
Third, third commanding to do with the raw resource is aggregate bunch of them together like if you have a planet that has a 30 forms and all of them are producing a harvest and collecting it at one point.
I have a list of raw resource that I want to ask to get and you just write it as a simple way of doing this.
And that way is monoid. I talked about monoids last time in detail.
So we need two instances semi-group and monoid because monoid needs a semi-group semi-group.
And these are just adding them. The semi-group instance has the time operation that takes two parameters and just add them together.
I don't have to deconstruct the parameters to get the hold of the int because earlier we defined the name instance.
We can just add them together. And the monoid instance needs a one function named D or an empty that is just raw resource zero.
The unit or zero element is a raw resource zero.
So both define again as a raw resource T so we are keeping track of that or rather the compiler is keeping track of that we are not mixing the types of different types of the raw resources.
And that is really the thing that I was after it was that the compiler keeps track of that we don't mix the resources and we don't have to keep spelling that out.
Like I mentioned earlier there are three different kinds of resources, chemical, biological and mechanical and I don't want to create many variables to move things around and manually keep track of them.
So I want to group them together. So when we are talking about the raw resources we have these three things together.
And this is a record called data raw resources are equals to raw resources and then three fields that are of type raw resource.
And here I am spelling them out these are raw resource mechanical, raw resource biological and raw resource chemical in the inside of the raw resources because the compiler needs that information.
And again there's a valve variable in the definition but it's not used into the right side of the equation so this is a again a random byte.
And yeah, the die parameter is used to keep track of what the meaning of this or what is the usage of this raw resource thing we have we have it and it can be cost of some project.
How fast the building of that project is progressing currently how much work is left, how much cost function has been done, how much free resources to have available.
Now we can say that we have a 500 units of all resources and then this project is worth of 1000 resources building is progressing 100 units per turn of each of them and we have done 100 units so far and there's a 400 units of work left.
Need little at least in my opinion to make sure that you don't make mix mix up the things.
And as earlier we want sometimes we sometimes want to combine these things for example we have a planetary level construction projects consisting of multiple buildings.
And somebody says that I want to know how much of resources we need all together and how do we do that again list of items that we want to combine together and that in this case means again in this case means that it's a monoid once again.
So defining a semi-group and monoid as before but this time for the raw resources is the for raw resource.
And if you check the zone notes you notice how the for example the semi-group instance is defined using the semi-group definition of the raw resource and monoid instances.
Define using a monoid of the raw resource because if one item is just a way to combine those one item single items that are held in the record then the semi-group of the record is combining those items one by one.
Like in this game in this game semi-group is combining of the semi-group result of the semi-group is for resources again with the first element or record element is the combination of the first elements second is the combination of the second elements of the two raw resources and third one is combination of the third ones.
You combine mechanical resources you combine the piles of resources and you combine the chemical resources likewise the monoid and MMP is you know that the raw that the MMP of the raw resource.
So you can just say that for the raw resources an MMP is an MMP for each of the record fields.
And this I actually even noticed when I was doing this episode I'm driving the zone notes I had defined the MMP for the raw resources.
And then I just explicitly stating that the mechanical resources is the raw resource 0, biological resource, resource equals raw resource 0 and chemical resource equals to raw resource 0.
Then I can just simply define it to be mechanical resource equals to MMP to use the definition of that for the single raw resource that I wrote out earlier.
Not a big thing but maybe the code looks nice.
Okay, so in the future, if I add exotic resources like delitium, unobtannium, adamantium, what do you name it?
I just have to add a new raw resource data in the same way that there's now three biological, mechanical and chemical.
I just say that the data delitium equals delitium.
And the system here works without any changes.
I cannot hold the delitium in the raw resources record but the popular one didn't case anyway.
This exotic resources will be something that is set to aside and keep track separately because there's a rare and they have a...
If I'm adding them, they will be rare and they will have specific purposes and so on.
But I think I'm going to call it off at this point.
This explains in sufficient detail what I'm doing with the resources and adding anything more will be just tracking out the episode.
So have you written something similar?
Or have you had a game where you had a resource management?
Have you been interested in hearing that you could figure out episode about that?
Or what do you think about the approach in general?
Okay, until next time, this is Duk.
Bye-bye.
You've been listening to Heka Public Radio at HekaPublicRadio.org.
We are a community podcast network that releases shows every weekday Monday through Friday.
Today's show, like all our shows, was contributed by an HBR listener like yourself.
If you ever thought of recording a podcast, then click on our contributing to find out how easy it really is.
Heka Public Radio was founded by the Digital Dove Pound and the Infonomicon Computer Club
and is part of the binary revolution at binrev.com.
If you have comments on today's show, please email the host directly, leave a comment on the website or record a follow-up episode yourself.
Unless otherwise status, today's show is released on the Creative Commons, Attribution, Share a Light, 3.0 license.