Jump to content

  • Log In with Google      Sign In   
  • Create Account

Servant of the Lord

Member Since 24 Sep 2005
Offline Last Active Yesterday, 08:42 PM

#5302189 My First Videogame Failed Conquering The Market

Posted by Servant of the Lord on 23 July 2016 - 12:06 PM

2D gameplay with 3D graphics is fine.


The graphics are definitely ugly for a game from the 2012, but still had 176k plays!


Ugly graphics and over 150.000 downloads both on GameJolt and Play Store


There must be something related to either gameplay, or the fact people thinks there is a bitcoin miner/malware inside my game i think.


It's likely not one thing that drives away all your customers. Likely some segment is driven away by bad graphics, another segment by bad gameplay (you can sorta detect this by your user metrics - did they play for ten minutes and never return?), another segment by never having heard of the game in the first place.


For me, I see this and it drives me away:



Since you want feedback, I take a second look and see the graphics actually aren't all that bad, but it has some garrish issues that prevent me from seeing that on my first glance - and most players will probably only give you that glance.


If you look at the picture as a whole, it is an vibrant lime-green burning my eyes like acid. The 3D modelling isn't bad, but the brightness of the yellow-green is pretty intense. I think even digitally altering this one image may get people in-game.


The problem is, a customer's eyes has to adjust to the garishness of the image before seeing that it doesn't look bad, but they aren't going to wait.

The second problem is, your eyes are already adjusted to it, so it's hard for you to see it. Try setting it as your desktop background, so you see it at unexpected times when your mind isn't prepared for it.


I think the game also suffers from a lack of shading. The bitcoin is flat, the blue arrow is flat, the fences don't seem to cast shadows.


Also your text is hard to read. Where it says "the bittles", for some reason the first word is in all lowercase, and the second word is in all uppercase. The first word is in one font, the second in another font. The first word is near invisible, and the second has a bunch of dots making it hard to read.


Honestly, I couldn't see the first word at all, and the second word at a glance looks like it says BITCHES rather than BITLES.


Further, "Bitles" is actually spelled wrong. I know it's a word you made up for your game, but it's actually spelled with two T's, unless you're localizing into French. English has rules and a certain feel to it, so even made-up words need to follow that.


I don't know the specific rules involved here, but intuitively:

"Bitles" reads as "Bit  less"

"Bittles" reads as "Bit tolls" (i.e. "a small bit")



Don't get discouraged. You've completed a game, which is incredible!


The problem now is, your game needs to be polished and refined.

I don't know the source of the quote, but "Polish is everything you do to improve your work AFTER you thought you were finished."


Or you can roll the knowledge gained into your next project... but to do that, you have to actually understand what's wrong about this project, or you might just repeat the same mistakes.


Oh, and I haven't played your game, I just saw that single image I re-posted in this post.

#5302033 Perspectives On Mod Makers?

Posted by Servant of the Lord on 22 July 2016 - 03:31 PM

Many games have become successes because of mods - that's part of what made Halflife a success. People wanting to play mods had to buy the base game.

Team Fortress, CounterStrike, and Day of Defeat came out of the Halflife mod community as well, and Valve hired the teams and made the games into successful full releases.(technically, TeamFortress came out of the Quake community, and Valve hired the team and ported the game to the GoldSrc engine).


DotA came out of the Warcraft 3 mod community, boosting sales for Blizzard.

Project Reality and DayZ boosted sales for ARMA 2 after its normal shelf life had already ended.


Since mods boosts of sales of their base games, many publishers and studios have noticed, and recognize it as a good thing - sometimes even providing some measure of tool support to help modders.

#5302002 Copying An Existing Idea

Posted by Servant of the Lord on 22 July 2016 - 12:44 PM

Sorry, I wasn't trying to say you were egocentric, I was just trying to unfold the idea more from the opposite perspective (i.e. the original game creator's perspective).



If I'd be the guy who made line rider I'd think: what an ass, that's my game.


This happens all the time.


Do you think the person who created the first match-three looks at the glut of poor mobile games (like the -saga games made by King, etc) and also thinks "what an ass. that's my game"...? Most likely.


In game marketing it's less about who came up with the idea first, but who markets it most successfully.


Another example is Angry Birds - it's just a catapult game, of which two or three existed before Angry Birds, but Angry Birds (due to marketing and so on) became a thousand times more popular (and more profitable).


I'd also feel bad, "That's my idea! *I* should've made buttloads of money!", but at the same time, every idea is built upon ideas that are built upon ideas that are built upon ideas, so while I'd be bummed out (for missing an oppurtunity), I still wouldn't support ideas themselves as copyrightable.


It also depends how close the two games are. Crayon Physics feels entirely different than Line Rider, though there are obvious similarities.

#5301867 Looking For 2D Pokemon Styled Assets

Posted by Servant of the Lord on 21 July 2016 - 09:18 PM

Try opengameart.org for your general needs, and then mock up ugly placeholder art (the uglier the better) for your game to use until your game is actually playable and far enough along development to be actually enjoyable to play.


Then, start showing your game on art sites, and artists will jump to provide better quality work.

(but it's a waste of their time and yours, for your game to have custom art before it's actually enjoyable and playable, because most game projects don't make it to completion)

#5301827 Mmorpg Idea.

Posted by Servant of the Lord on 21 July 2016 - 03:16 PM



You probably don't want to post your email publicly on the internet, because armies of bots read the internet looking for email addresses to send spam to.


By playing A LOT of mmorpgs I know what they need and how to improve them.

That's a popular thing to say, but is mostly wrong.
You improve at a skill (like game design) by researching, practicing, discussing, AND playing.

For example, this doesn't make sense: "By eating A LOT of food, I know how to improve cooking."
People get better at cooking by eating, reading, cooking, and talking with other cooks. Not only by eating.


Playing games is not the same thing as research.  :wink:

Every class has their own specialties:
Mages - Healing and supporting party,
Knights - Receiving damage and defending teammates,
Juggernauts - Reducing enemies' Defenses/Resistances while dealing medium damage.
Archers - Dealing a lot of damage to both single and multiple targets.

How is any of this new and improved over existing MMORPGs? This looks like the same kind of gameplay I played two decades ago with Everquest.

Collect 10 Wood.

We've been collecting X objects, visiting Y locations, and killing Z enemies for decades. :(

How about something new?



When cooking, you don't take everything that's good and mix it into one pot - it'd make a disgusting mess.

Game Design is not taking everything cool or fun and mixing it into one game - it'd make an unbalanced and boring game.


I'd really love to hear some interesting new game designs you can come up with, but first it has to be refined by several years of research. If you want to do some research, I'd suggest looking up Raph Koster; the Gamasutra website is also a good source of information, as well as the Extra Credits YouTube channel.

#5301799 Why didn't somebody tell me?

Posted by Servant of the Lord on 21 July 2016 - 11:35 AM

[...] my root drive typically looks like this:

D:\bin → "Program Files"
D:\bin86 → "Program Files (x86)"
And so, if i want to go to "D:\bin\python\35": winkey+E, D:, enter, b, b, enter, python, ...

Are you symbolically linking 'bin' to "Program Files", or were you just explaining what 'bin' is, for conformist Windows-using lemmings like myself?

#5301683 Trusting The Client

Posted by Servant of the Lord on 20 July 2016 - 11:09 PM

Most small games will never take off.  Those that get a small success are unlikely to ever be attacked or hacked.
However, in the extremely unlikely event the game starts to be popular then people will attack the protocol and find ways to abuse them. A few bad actors could ruin the popularity in an instant by finding the exploit.

I've only been a part of the development of one online game so I don't know how far this holds in general. Though we never left 'beta', and only had <30 active users at most, some of our active users repeatedly tried to exploit the game by manipulating the data packets, manipulating the game itself (mostly using CheatEngine), and so on. Luckily they were just script-kiddies in our case. Still was a bit of a nuisance though. We were also DDoS'd several times, and (from other users) had multiple racially-explicit and sexually-explicit verbal harassment incidents.


If users like your game enough that they keep returning, I'd theorize that they'd also like your game enough to cheat and grief, regardless of how successful the game is.

i.e. if 1 out of 10 users (for example) are griefers, they aren't going to 'not grief' just because the community is small. If 1 out of 10 users are cheaters and script kiddies, they're still going to muck with your security even if the game is small. If 1 out of 10 users are verbally racist and sexually harassing, they're still going to be racist and sexist even when the community is small. Perhaps moreso, because they are more in the spotlight.


Ofcourse with a larger community, you get more racists, more griefers, more cheaters, more script-kiddies, and perhaps even a few real hackers. But the probability of rolling a "cheater" for each new user you get is much higher than 0.

#5301581 Copying An Existing Idea

Posted by Servant of the Lord on 20 July 2016 - 10:20 AM

At least for me, the law doesn't map my moral/ethics at all - and I hope that's true for you too.

The law does not perfectly map to my morals (pretty far from it), but it makes a reasonable attempt to map to the lowest-common-denominator morals of the average public (and also gets influenced by politics and corporations).

But to say the law doesn't map at all is an exaggeration, unless you find murder and rape acceptable.


Or are you talking only about copyright law? If so, do you understand copyright law enough to recognize the morality behind it? If you don't understand why it exists - i.e. you haven't listened to the arguments for it - then how can you say you disagree with an argument you never listened to? And if you don't understand how the law works, how can you say you disagree with what you don't understand?  :) 

If I would do it, I'd contect him and ask him, maybe ask him to help me, just because he came up with this idea.

"Hi! I'm going to use your work for my profit, but before I do, I'm going to give you the ''opportunity'' to help me steal your work. I'm not going to ask permission, and I'm not going to let you have any say in the matter, but out of the goodness of my heart I'll give you the option of using more of your labor to help me do what I want."


Do you not see the self-centered / one-sidedness here? Basically it's saying, "I want to do whatever I want, and screw you for standing in my way, but I also want to pretend I'm a decent person, so I'll make hyper biased one-sided offers to feel better about myself.". Your offer is, "Heads I win, tails you lose". It's "Heads I get to use your work with your permission, tails I get to use your work without your permission.". You don't give anyone opportunity to not have their work exploited for your personal gain.

('profit' doesn't have to be money - it can be publicity, praise, pats on the back, donations, cookies, twitter followers, or warm fuzzy feelings. You profit off of it even if you don't charge anyone money for it)
(also, creating the cloned IP is damaging the real thing in several subtle ways, even if you don't charge any money for it)


Suppose you created a really popular character like Master Chief (Halo). And the real-life KKK comes along and uses Master Chief to promote ethnic cleansing of black people. "Master Chief wants your help in eliminating the inferior races!". Your work has now been used to promote ideas you find despicable. It's funny in concept, but not funny if it actually happened, and your actual work was actually being used to do actual harm to actual people.  :mellow: 

TO clarify: What I mean is e.g.: Assume Super Mario was the first Jump'n'Run. You now do a game, which also is 2D and has a level which goes from left to right and you jum around, collecting stuff, beating monsters. Like there are dozends of such games. Another Example would be line rider. But instead of the sled you are going to use seomthign else, might add a few elements etc - but the main mechanics (a player dragged down on a self painted rack) is baisically the same. (all developed by you)

Anyone can make games inspired by the ideas and mechanics behind other games.

The ideas behind side-scrolling 2D platformers are not intellectual property, and are not protected. The art, music, characters, names, enemies, code, and level designs are protected. And, while no specific math equation in Super Mario Bros is protected, if you take too much of the numbers and equations used in the same way, then it can also be a problem.
For example, some iPhone games have been sued because they had in-game stores featuring the exact same items (even with different pictures), with nearly the exact text, and exactly the same prices (even with different currency type), as the game they were cloning. It was obvious that they were stealing more than just ideas - they were stealing implementations of the ideas.

Basically it comes down to, how much are you actually creating something new vs how much are you taking what other people did?
If players say, "Hey, this kinda reminds me of OtherGame" that's fine. But if players say, "Hey, this is exactly like OtherGame, except with X instead of Y", that's not fine.

If I have to ask, "How close can I get to entirely stealing someone else's work?" then I'd be failing. I'd be failing legally, I'd be failing morally, and I'd be failing as an artist - because you aren't making art, you'd just be scanning someone else's art and selling the prints.

I want to be a game creator, not a game cloner. I want to be an artist, not a xerox machine.  :wink:

#5301390 Copying An Existing Idea

Posted by Servant of the Lord on 19 July 2016 - 12:12 PM

Do you think that's a bad move without asking the guy who had the initial idea? I mean, isn't it basically stealing?


You have to define what you mean by "idea". Separate "idea" from the work used to implement the idea. Are you taking someone's work and profiting off it? That's one direction that morals can be explored - sometimes it's fine, othertimes it's not; it depends.


As for ideas itself, historically, ideas are seen as public goods. For example "machine that harvests wheat so humans don't have to". That's an idea. Everyone is then free to compete trying to inventdesign, engineer, and build, such a machine.


It's that inventing, designing, engineering, and building, that is protected by law. It's generally considered acceptable to compete by taking ideas and coming up with your own implementations.


In some countries (most of the western world), it's not considered acceptable to steal the implementation until the author has had X number of decades to profit from it. Implementations is what patents and copyrights cover (patents cover processes, copyrights cover designs - processes ("how to build") and designs ("what to build") are implementations of ideas - but the ideas themselves aren't protected. This is a very simplistic overview, it's more in-depth than that).


Essentially, vague ideas ("a ninja that fights someone", "a machine that harvests grain") are fair-game, but the more implementation you take (Naruto, the specific machinery that runs a tractor), the more it's frowned upon - by law and by (western) humans.


This copyrights and patents are a decision Westerners made several hundred years ago, for the benefit of the public, recognizing that letting creators have a period of profit encourages creators to create.


(copyrights and patents do get abused by corporations due to problems in our legal system, and need to be re-balanced, but the core idea behind them has been beneficial to everyone including the public)


So basically, are you taking a game (loads of someone else's work) and merely tweaking a few things, or are you taking the idea behind a game, and creating something different? There is a wide range of degrees there, and unless you narrow down to specifics, discussions of legalities and moralities is pointless. And since copyright and patents are a purely human invention, the morality discussion partly takes the form of "are you a law unto yourself, or do you live alongside other humans under common guidelines of interaction".

#5301159 Basic Multithreaded Question

Posted by Servant of the Lord on 17 July 2016 - 11:15 PM

Can a 64 byte char array start in the middle of a cache line and overlap the next?

Sure. The compiler usually word-aligns variables for you, in structs and so on, but doesn't cache-align it unless you ask.
(with char arrays, it may be a little different, since chars are often used as raw bytes)

Is there a way to ensure that the data starts at the cache line?

If you have your own allocator, you can align it to whatever you want (even bad alignments that the CPU chokes on).

But also, look at alignas().

#5301158 Basic Multithreaded Question

Posted by Servant of the Lord on 17 July 2016 - 11:04 PM


Copying the array means either one of two things: A) Your array is so small that copying is cheap; if it's that small, you shouldn't be multithreading it anyway. or B) The array is large, but you're taking the easy way out instead of understanding the problem (which sometimes is the economic thing to do, if you don't have time to waste doing the research).

Or the array is small and cheap to copy, but the computation you're performing is expensive and makes sense to spread over multiple threads...

That was mentioned previously; I conceded that point already.  :wink:

Doing a quick read up on cache lines, it appears that Intel architecture cache lines are 64 byte. So if the data is divisible by 64 like a 1024 byte array, this should avoid performance hits shouldn't it?

Again, noob here. From what I understand, whatever size the array is, regardless of whether it's divisible by cachelines or not, as long as more than one thread is not accessing (with at least one writing) the same cacheline around the same time (and as long as you aren't shuffling the same cacheline back and forth between the two threads), you should be fine in avoiding the speed-trap I mentioned.
Basically, if you are giving half of your array to different threads, you probably want to make your dividing point be aligned to a cache-line, even if it means giving one thread a few elements more of data (and ofcourse, without cutting an element in-half). So if your array happens to be (roughly) 3 cachelines, give two to one thread and one to the other, rather than 1.5 to both. (I say 'probably', because yes, if you are operating on a small amount of data, but doing a large amount of processing, that certainly changes how the code ought to be written).
If whatever chunks you give your threads don't contain overlapping cachelines segments that they are simultaneously trying to access, and other unrelated threads in your program aren't trying to access the same cachelines, you're fine. By "access", if every thread is only reading, you're fine, but if even one thread is writing, that means the read's of the other threads need to re-cache the written-to values (which means re-copying the entire cache-line up and then down the caches).
But if you ping-pong the cache, that can be slow too. Even if ThreadA and ThreadB aren't accessing the cache at the same time, if they alternate who accesses it, each alternation (if a write occurred) requires syncing the memory between their different L1 caches (if they are using different L1 caches).

ThreadA writes to [line of bytes]
ThreadB writes to [line of bytes] //Forces re-syncing the memory up and then down the caches
ThreadA writes to [line of bytes] //Forces re-syncing the memory up and then down the caches
ThreadB writes to [line of bytes] //Forces re-syncing the memory up and then down the caches

It's (conceptually) faster to do:

ThreadA writes to [line of bytes]
ThreadA writes to [line of bytes] 
ThreadB writes to [line of bytes] //Forces re-syncing the memory up and then down the caches
ThreadB writes to [line of bytes]

But if alot of other memory is being accessed in-between access, it doesn't matter, since it's likely been pushed out of the L1 or even L2 caches anyway.
(which is where the obligatory "profile profile profile" comes in)
A) Each time a thread wants to access [cachline #23424]. if it's not already in the local L1 cache, it has to read to L2 cache, and then to main RAM (or L3 if it exists, then main RAM). So accessing a cacheline a second time while it's still in the L1 cache is faster than accessing it when it's not in the L1 cache (which is the point of the cache).
You already know (A). What I'm trying to adding is:
B) If you have the same cacheline copied to two different L1 caches, and one of those copies gets written to, then the other copy will have to get sync'd before your next read or write goes through, and that can be slow. Once or twice is no biggy, but I'd suspect that if it's happening once after divying up tasks for threads, it's likely happening more than once, and it'd be better to guarantee cacheline exclusivity.
So my inexperienced suggestion would be, when dividing up your thread *workloads* (irregardless of you copying or not copying memory) make sure the workloads are on cache-boundries, and let those threads have exclusive access to those cachelines until they complete their work. This doesn't necessarily affect the allocated size of your array itself, but padding out the beginning/end of the array to ensure other threads aren't using that memory wouldn't be a bad idea.

#5301132 Basic Multithreaded Question

Posted by Servant of the Lord on 17 July 2016 - 09:43 PM

Copying the array means either one of two things:
A) Your array is so small that copying is cheap; if it's that small, you shouldn't be multithreading it anyway.
or B) The array is large, but you're taking the easy way out instead of understanding the problem (which sometimes is the economic thing to do, if you don't have time to waste doing the research).

If you are going to take the easy way out, the easiest way is leaving it singlethreaded. But if you are wanting to multithread it, you can do so without splitting up the array.


Another easy and safe way to split up workloads is to use a single thread and simply do half the array on odd frames, and the other half on even frames. Depending on the nature of your problem.

Generally, yes it will be ok... but technically it's unsafe, and you need to be aware of the actual compiler/hardware behavior to justify it as being safe to do.
To get into specifics... if you're compiling for a PC (x86 / x86-64), then the CPU can atomically write 4-byte sized variables.
If the elements within your array have sizeof/alignof > 4, then you'll be ok.
If the elements within your array have sizeof < 4, then you're in trouble
e.g. say you've got an array of six unsigned short's, shared by two threads:

| thread 1  | thread 2  |
|block 1|block 2|block 3|
As far as the CPU is concerned, it can only read or write to these 4-byte blocks, labelled block 1/2/3 above.
So if thread#1 tries to write to index [2] and thread 2 tries to write to index [3] at the same time, then both threads will be performing a read-modify-write operation on "block 2", which is a race condition.


You're talking about making each variable word-aligned. But isn't another issue ensuring that two threads aren't operating on the same cache-line at the same time as well?
I'm an noob when it comes to multi-threading (i.e. I read about it but have never played with it), so correct me if I'm wrong here, but shouldn't each work-load be cache-aligned if there is a chance that at least one of the two threads will write something to the same cache that the other thread wants to read from, or the memory will have to be repeatedly shuffled from CoreA's L1 up to L2, L3, or even main RAM, and then back then to CoreB's L1, if the hardware architecture means they aren't sharing the same cache (e.g. if the two threads aren't hyperthreads on the same core).
Wouldn't that shoot your performance in the foot? i.e. if your elements aren't word-aligned, you can have undefined behavior. But even if word-aligned elements, if your thread workloads aren't cache-aligned, you might have unexpected and hard to detect slowdowns. I think.  :ph34r:

#5300926 Overall Strategy For Move-Semantics? [C++11]

Posted by Servant of the Lord on 15 July 2016 - 03:23 PM

Option 4 is promoted by some of the standard committee members. My mind has accepted the reasoning, but my fingers refuse to type it.  :P


Mostly I just pass by const ref, and use r-value ref when needed.


However, const-ref for when copies aren't needed, and pass-by-value when copies are needed are technically the correct way. My only "problem" with it is that it prevents me from forward-declaring classes (since pass-by-value requires the full class definition).


Option 4 looks a bit messy since it implies the caller has to think about this problem. 


Assume you have a member function like this:

void MyClass::SetText(std::string text)
     this->text = std::move(text);

The requirement is, the class needs its own variable that it can modify without affecting external variables (i.e. a reference/pointer/handle to an externally owned variable is for some reason unacceptable in this circumstance - we'll assume the class' requirements have actually been designed well).


Since a copy is going to be made anyway, caller behavior is thus:

99.9% of the time, the caller doesn't need to think. If he isn't explicitly giving up ownership of his copy, the function then makes its own copy.

myClass.SetText(variableWeStillWantToUse); //Does a copy - like normal.


If the caller happens to call it with a literal or otherwise short-lived value (i.e. an 'r-value'), then the function silently does a move instead of a copy.

myClass.SetText("variable that is a literal"); //Does a move - a small optimization.
variableWeStillWantToUse = "The time is now %time%";
myClass.SetText(variableWeStillWantToUse.format(getTime())); //Does a move on the return-value of the format() call (if it's a temporary).


But, if the caller knows that he's not going to use the variable anymore, he can explicitly choose to give up ownership:

myClass.SetText(std::move(variableWeStillWantToUse)); //Does a move.

This last one would be "premature optimization" in most cases; callers generally, 99.9% of the time, shouldn't be calling std::move().

Callers never have to think about this, unless they want to make that micro-optimization.


The *default* is business as usual with automatic micro-optimizations taking place on variables that the function already knows are temporary (like literals, or the results of function calls like (25 + 17) or something.format(str)).


Being able to call std::move() explicitly is an added bonus (or a distraction) for callers, but one they don't have to think about. Essentially, move-semantics was added to provide automatic micro-optimizations, with no change necessary in caller-behavior, and only (opt-in) changes for class/function writers.


You'd still use const-ref for variables you don't need copies of, and references/pointers/handles for variables you want shared or owned elsewhere.


Ofcourse, compilers will still do RVO to avoid even the moves, when possible, but when not possible, the moves are equal or superior to copies (a move is essentially a 'shallow-copy' with transfer of ownership, whereas a copy is a 'deep-copy', if the class has (for example) pointers to allocated memory or file handles or whatever).


The only problem with pass-by-value is that you can't forward-declare your variables, which makes it a no-go for me most of the time.  :P

#5300897 Using Military Designs

Posted by Servant of the Lord on 15 July 2016 - 09:07 AM

so nothing without license.


But is there anything I can use without licence or I need to be a multi-billioner just to make one movie?


Design custom helicopters and jets?


Game designers, movie makers, and so on need to get together and make a completely creative-commons archive of original and well-designed cars, guns, planes, etc... that everyone can use.

#5300802 Slavery, Include Or Not?

Posted by Servant of the Lord on 14 July 2016 - 04:23 PM

It's definitely a decision you have to think about carefully.


Personally, I think including slaves, and depicting slavery harshly, can make a game more intellectually interesting.


But it's a difficult balancing act you can't commit to halfheartedly:

 - Slavery needs to be depicted...

 - ...but not glorified. You don't want players to play the "Dark Side Jedi" and gleefully participate ("I'm only roleplaying!/It's only a game!").

 - ...but the game itself still needs to be fun and enjoyable, and not too somber.

 - The cruelties need to be explored and demonstrated...

 - ...but not glorified. You don't want some people to enjoy the portrayal of domination and subjugation feeding their fetishes.

 - ...but not minimized. Slavery, while commonplace in that time period (and today as well), shouldn't feel 'normal' to the players.


You have to balance being preachy and ham-fisted, with not indulging people's fetishes, not accidentally teaching that slavery is profitable (despite that being the reality), but also not minimizing or treating it casually.


I remember reading about a teacher teaching a class about the African slave route, and had students load up their boats with "humans" and give each person a name and family members on the crew. Then they began crossing the Atlantic, and (by rolling dice), named slaves were thrown overboard, died from starvation, died from disease, etc... etc... with the end result that few made it to the other side.


I think the easiest way to do this safely, is to make players observers and not engages with the slavery, or to reveal after the fact that actions they took furthered some horrendous crime.


In a board game that you replay, I think the deaths and abuses become too commonplace in players' minds, so I'd save those kinds of explorations to single-player games that players usually only play through once or twice.


If you do wish to add slavery, maybe slave traders are a non-player dynamic that's occurring in the world that interact with players but that the players never get an opportunity to profit from. If the game already has the player have crews, maybe name each crew (players draw cards for their crew members) and the crews have different stats and maybe can be upgraded, so players attach to the players, and suppose some of the players' own crew gets randomly captured by slavers, and they find out (three or four turns later) what that person's fate was (what kind of death, what kind of slavery, in what location, from what slave ship), and maybe players have the opportunity at capturing slave ships, freeing the slaves (and risk sinking the ship and drowning the hundreds of slaves chained up in the hull). Or something.