Be a Supporter!

Text Adventure: cross platform lang

  • 445 Views
  • 25 Replies
New Topic Respond to this Topic
uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Text Adventure: cross platform lang 2013-06-01 19:49:07 Reply

I've got decent programming skills, but I want to learn a new language =^)

What would be the best programming language to program a text adventure game and make it be able to be played on Windows, Mac OSX and Linux? (Running it in a Terminal or command line window as you probably was thinking already)

The languages I've been thinking about:
- C
- C++ (Is C++ a bit overkill for a text adventure game?)
- Python
- Or other languages that you'll recommend.

Diki
Diki
  • Member since: Jan. 31, 2004
  • Offline.
Forum Stats
Moderator
Level 13
Programmer
Response to Text Adventure: cross platform lang 2013-06-01 21:34:18 Reply

If you want it to be simplest for the end-user your best bet would probably be Java since you will only need to compile the application once; the resulting .jar file can be copy/pasted to any operating system that has Java installed and be used without issue.

Python or Ruby would be good choices as well but compiling them into run-time executables for Windows, OSX and Linux will require a little extra work. In my opinion Python and Ruby are much better languages than Java but the usefulness of the JVM for simple applications, such as what you're doing, is hard to pass up.

You could also do it in Perl, but Perl is kinda goofy. Up to you.

At 6/1/13 07:49 PM, uglybetty wrote: - C
- C++ (Is C++ a bit overkill for a text adventure game?)

Unless you have a compelling reason I can't recommend either language for a text adventure game. They're very complex and difficult to learn languages, and just overall aren't as well suited for text-based games as other languages are.

If it came down to it though I would definitely recommend learning C before C++. It is much easier to learn C++ after C then it is to learn C after C++.

uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-01 22:14:15 Reply

At 6/1/13 09:34 PM, Diki wrote:
At 6/1/13 07:49 PM, uglybetty wrote: - C
- C++ (Is C++ a bit overkill for a text adventure game?)
Unless you have a compelling reason I can't recommend either language for a text adventure game. They're very complex and difficult to learn languages, and just overall aren't as well suited for text-based games as other languages are.

If it came down to it though I would definitely recommend learning C before C++. It is much easier to learn C++ after C then it is to learn C after C++.

Ok. The reason I'm mainly doing this is to get a wider experience in overall programming languages.

The thing is that should I be careful when programming cross platform?
Header files - are there standard header files that are supported on all systems?
Diffrent functions etc ?

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-02 04:33:56 Reply

At 6/1/13 10:14 PM, uglybetty wrote: Header files - are there standard header files that are supported on all systems?
Diffrent functions etc ?

For a text based adventure not really, the only problem you might run into if you are going to use some time based actions, then you might want to avoid clock() because it has a very bad precision on some machines (under linux for instance it's one second, so the value it returns only changes once every second) and use gettimeofday(unix) and timegettime or queryperformancecounter(windows) instead.
Also if you're using C, the case insensitive string compare function is stricmp in windows and strcasecmp in unix, but other than that it's highly unlikely that you'll find anything.

Diki
Diki
  • Member since: Jan. 31, 2004
  • Offline.
Forum Stats
Moderator
Level 13
Programmer
Response to Text Adventure: cross platform lang 2013-06-02 08:49:37 Reply

At 6/1/13 10:14 PM, uglybetty wrote: The thing is that should I be careful when programming cross platform?

When writing C/C++ yes. As kiwi-kiwi pointed out there's a couple differences between Windows and Unix-based systems. If you choose to write Java, Python, Ruby or Perl you won't need to worry about that.

At 6/1/13 10:14 PM, uglybetty wrote: Header files - are there standard header files that are supported on all systems?

Yes. If you're writing C/C++ you have no good excuse to not be using header files. Just use them correctly; don't do something stupid like putting your class and function definitions in headers (if you're writing C then you can ignore what I said about classes since C doesn't have them).

Thegluestickman
Thegluestickman
  • Member since: Mar. 16, 2007
  • Offline.
Forum Stats
Member
Level 13
Game Developer
Response to Text Adventure: cross platform lang 2013-06-02 11:10:01 Reply

Java and Python has cross-platform capabilities, but Java is kind of a clunky language.

You could try HTML5 and Javascript, you could play it on any modern browser and submit it to NG. You could C# under the mono implementation as that's cross-platform. The choice is really all yours.


To protect the world from devastation.
kidd25 is the best Newgrounder ever.

BBS Signature
amaterasu
amaterasu
  • Member since: Mar. 7, 2004
  • Offline.
Forum Stats
Member
Level 08
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-02 14:50:39 Reply

Here's another option for cross-platform game development:

http://monogame.codeplex.com/


beep

BBS Signature
Thegluestickman
Thegluestickman
  • Member since: Mar. 16, 2007
  • Offline.
Forum Stats
Member
Level 13
Game Developer
Response to Text Adventure: cross platform lang 2013-06-02 18:42:16 Reply

At 6/2/13 08:49 AM, Diki wrote: Yes. If you're writing C/C++ you have no good excuse to not be using header files. Just use them correctly; don't do something stupid like putting your class and function definitions in headers (if you're writing C then you can ignore what I said about classes since C doesn't have them).

Quick question Diki, what's the difference between a struct and a class?

Also, is this a stupid way to use headers?

File "grandparent.h"

#pragma once
 
struct foo 
{
    int member;
};

File "parent.h"

#include "grandparent.h"

File "child.c"

#include "grandparent.h"
#include "parent.h"

To protect the world from devastation.
kidd25 is the best Newgrounder ever.

BBS Signature
kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-03 00:47:07 Reply

At 6/2/13 06:42 PM, Thegluestickman wrote: Quick question Diki, what's the difference between a struct and a class?

structs are more of a C concept that was kept around for backwards compatibility reasons, in C++ the only difference between a struct and a class is that members declared without an access modifier are considered to be public in a struct and private in a class.
Back in C, structs don't have member functions first of all and they were used to group together a number of variables and that's it. Plus, using them was a lot more weird than C++, when you declared a struct variable you had to explicitly tell the compiler that the type of the variable was a struct, I'm not really sure why though, maybe they thought that by adding an extra keyword they'd avoid name clashes, but meh.
Example:

struct Foo
{
    int a;
    int b;
}

int main()
{
    struct Foo myStruct;
    return 0;
}

However as you can guess no one really wanted to type that extra word so everyone did this instead

typedef struct
{
    int a;
    int b;
} Foo;

int main()
{
    Foo myStruct;
}

Which is probably why it's no longer required to do so in C++

Also, is this a stupid way to use headers?

File "grandparent.h"

#pragma once

#pragma once is visualc specific, if you want to move the code to another compiler you're going to have to use include guards.

struct foo
{
int member;
};

File "parent.h"

#include "grandparent.h"

Careful when including .h files in other .h files. If you only use the type from the included file with pointers or references then you don't need to #include it's h file, you can make a forward declaration (struct foo;) and then use it in the h file definitions and #include the h file in the cpp file that uses whatever you defined in parent.h. You want to do this to minimize the effects of making any change to grandparent because if you #include grandparent into parent then everything that #includes parent will also get recompiled when you change grandparent, it's sort of a domino effect that you really want to avoid if you want to keep build times low.

File "child.c"

#include "grandparent.h"
#include "parent.h"

If you #include grandparent into parent there's not much of a reason to include it again, but there's no harm either because of the #pragma once so no biggy.

Diki
Diki
  • Member since: Jan. 31, 2004
  • Offline.
Forum Stats
Moderator
Level 13
Programmer
Response to Text Adventure: cross platform lang 2013-06-03 08:33:39 Reply

At 6/2/13 06:42 PM, Thegluestickman wrote: Quick question Diki, what's the difference between a struct and a class?

This was already answered by kiwi-kiwi but, just as he said, a struct has public members by default and a class has private members by default. That's the only difference.

At 6/2/13 06:42 PM, Thegluestickman wrote: Also, is this a stupid way to use headers?

File "grandparent.h"

#pragma once

struct foo
{
int member;
};

File "parent.h"

#include "grandparent.h"

File "child.c"

#include "grandparent.h"
#include "parent.h"

It's difficult to say since this doesn't really have any code, but I do agree with kiwi-kiwi that you should use include guards instead of #pragma once.
Earlier, when I said to not put definitions in headers, what I meant was this:

myclass.hpp

#ifndef _MYCLASS_HPP_
#define _MYCLASS_HPP_

class MyClass {
private:
    int __num;
public:
    MyClass(int n) : __num(n)
    {}

    int getNum() const {
        return __num;
    }
};

#endif

Both the constructor and getNum functions have been defined which is a no-no. Doing that makes your code more difficult to maintain, isn't the standard way of doing things, and also makes it possible for those functions to be compiled as inline (which could end up being counter-productive depending on the complexity of the function).

The way that should be done is like this:

myclass.hpp

#ifndef _MYCLASS_HPP_
#define _MYCLASS_HPP_

class MyClass {
private:
    int __num;
public:
    MyClass(int n);
    int getNum() const;
};

#endif

myclass.cpp

#include "myclass.hpp"

MyClass::MyClass(int n) : __num(n)
{}

int MyClass::getNum() const {
    return __num;
}

That way the declarations are kept in the header files and the definitions are kept in the source files. Much better. :)

Of course there are exceptions to this (such as when you're using a templated class/function) but, generally speaking, if you have to ask then it's probably better for you to follow this convention.

Oh-Sama
Oh-Sama
  • Member since: Dec. 10, 2009
  • Offline.
Forum Stats
Member
Level 27
Art Lover
Response to Text Adventure: cross platform lang 2013-06-03 08:37:00 Reply

I would like to say :D
I wish you good luck cauz I love this kind of games ^_^

uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-07 02:07:42 Reply

So I have started on the game :) I'm using C!

But I have one problem when getting user input and checking it. I'm trying to only accecpt if the user inputs up or down when choosing the path.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

     int main ()
       {
        char path[80];
        while(strcmp (path,"up") != 0 || strcmp (path,"up") != 0){
        scanf("%s", &name);
        getchar();
        }
     }
Filarius
Filarius
  • Member since: Aug. 16, 2005
  • Offline.
Forum Stats
Member
Level 14
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-07 04:01:38 Reply

At 6/7/13 02:07 AM, uglybetty wrote: So I have started on the game :) I'm using C!

But I have one problem when getting user input and checking it. I'm trying to only accecpt if the user inputs up or down when choosing the path.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
char path[80];
while(strcmp (path,"up") != 0 || strcmp (path,"up") != 0){
scanf("%s", &name);
getchar();
}
}

I really not get what exactry problem you have.
Sorry me for not writing on C looong ago, but I think what :
:strcmp (path,"up") != 0 || strcmp (path,"up") != 0
is equal if you write only
:strcmp (path,"up") != 0
also I prefer to write each boolean statment in brackets, just to be sure program will work in way I want
Is it only part of code? You compare path with "up", but I do not see any place you write to path anything


<== This russian guy always write with mistakes.

Rawnern
Rawnern
  • Member since: Jan. 24, 2009
  • Offline.
Forum Stats
Member
Level 28
Movie Buff
Response to Text Adventure: cross platform lang 2013-06-07 08:40:20 Reply

At 6/7/13 04:01 AM, Filarius wrote: I really not get what exactry problem you have.
Sorry me for not writing on C looong ago, but I think what :
strcmp (path,"up") != 0 || strcmp (path,"up") != 0
is equal if you write only
strcmp (path,"up") != 0
also I prefer to write each boolean statment in brackets, just to be sure program will work in way I want
Is it only part of code? You compare path with "up", but I do not see any place you write to path anything

Oh my. It was meant to say strcmp (path,"up") != 0 || strcmp (path,"down") != 0

Diki
Diki
  • Member since: Jan. 31, 2004
  • Offline.
Forum Stats
Moderator
Level 13
Programmer
Response to Text Adventure: cross platform lang 2013-06-07 10:09:31 Reply

At 6/7/13 02:07 AM, uglybetty wrote: So I have started on the game :) I'm using C!

But I have one problem when getting user input and checking it. I'm trying to only accecpt if the user inputs up or down when choosing the path.

As Rawnern pointed out you're checking against the value "up" twice.

At 6/7/13 02:07 AM, uglybetty wrote: scanf("%s", &name);

Did you mean to use &path here?
What is name?

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-07 14:45:37 Reply

At 6/7/13 02:07 AM, uglybetty wrote: scanf("%s", &name);

Apart from the errors that the others mentioned, there is also this one which is 99% likely to crash your program, let me explain why
When you use scanf, you have to give it the format string which is really easy to get and an address to the place it should put the data once it gets read. Now in C you have two basic types of declaration as follows:

int a;
int b[10];

The first one tells the compiler that a is a value of the type int and everytime you refer to a, you refer to the value that is currently kept by a, so in this case it makes sense to use &a for scanf to read because if a were let's say 10, then scanf would try to put the int in the memory location at the address 10 which is very likely not accessible by your program, so the operating system will send a sigsegv to the program and the program will crash.

In the second case however, the compiler understand that it should create 10 ints one after another and that b should be the address of the first one, so that when you say scanf("%d", b) you are telling scanf to read an int into the first element of b, so in this case if you use scanf(%d, &b) then you would actually be writing at the address which points to the place where the address of the first int from b resides, this is like &(&a) (PS I've never actually tried to do &&a, but i'm pretty sure it makes an error, so that expression is strictly theoretical). In your case if you use &path, scanf would start to write over the address of path and the continue to write in place in memory that it shouldn't touch which will in turn make the operating system crash your program.

So TL;DR you need to use scanf("%s", path); there, otherwise your program might crash

uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-08 02:57:26 Reply

At 6/7/13 02:45 PM, kiwi-kiwi wrote:
At 6/7/13 02:07 AM, uglybetty wrote: scanf("%s", &name);
Apart from the errors that the others mentioned, there is also this one which is 99% likely to crash your program, let me explain why
When you use scanf, you have to give it the format string which is really easy to get and an address to the place it should put the data once it gets read. Now in C you have two basic types of declaration as follows:

int a;
int b[10];

The first one tells the compiler that a is a value of the type int and everytime you refer to a, you refer to the value that is currently kept by a, so in this case it makes sense to use &a for scanf to read because if a were let's say 10, then scanf would try to put the int in the memory location at the address 10 which is very likely not accessible by your program, so the operating system will send a sigsegv to the program and the program will crash.

In the second case however, the compiler understand that it should create 10 ints one after another and that b should be the address of the first one, so that when you say scanf("%d", b) you are telling scanf to read an int into the first element of b, so in this case if you use scanf(%d, &b) then you would actually be writing at the address which points to the place where the address of the first int from b resides, this is like &(&a) (PS I've never actually tried to do &&a, but i'm pretty sure it makes an error, so that expression is strictly theoretical). In your case if you use &path, scanf would start to write over the address of path and the continue to write in place in memory that it shouldn't touch which will in turn make the operating system crash your program.

So TL;DR you need to use scanf("%s", path); there, otherwise your program might crash

Thank you so much! Programming in C IS MUCH harder than I thought! The whole thing about declearing strings and all that is really hard! But in my defence: It's my first C program.

But one problem after another: my program does not pause on getchar();. It looks like the while loop completely ignores it.

while(strcmp (path,"up") == 0 || strcmp (path,"down") == 0){
        printf("\nDo you want to go up or down? ");
        scanf("%s", &path);
        getchar();
        }
kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-08 04:12:37 Reply

At 6/8/13 02:57 AM, uglybetty wrote: But one problem after another: my program does not pause on getchar();. It looks like the while loop completely ignores it.

That's because it does, there was something about scanf, it reads from a buffer and when you press enter there are some characters that are left in that buffer, so if you call getchar right after it's going to read those characters that are left and it would seem as if it gets skipped. There are two ways to get rid of this, either do a fflush(stdin) or setvbuf(stdin, 0, _IONBF, NULL);
The first one surely works, I'm not very sure about the second.

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-08 07:26:14 Reply

Uh, yeah, neither worked for me under linux for some reason, I recall using them under windows for homework for university, but I think there's something about the line buffering that linux terminals have. fflush(stdin) is undefined behaviour so gcc is free to do whatever they want, including nothing and the setvbuf call should have removed the line buffering altogether, but there's probably something the system does in the back that makes that call useless.

In any case here's something that works

#include <stdio.h>

#ifdef __linux__
#define StrCmpNoCase strcasecmp
#endif

#ifdef _WIN32
#define StrCmpNoCase stricmp
#endif

int main()
{
	char command[256];
	printf("Minimal Text Adventure\n");
	printf("Available commands: exit, up, down\n");
	while(StrCmpNoCase(command, "exit") != 0)
	{
		printf("Enter your command: ");
		scanf("%s%*c", command);
		if(StrCmpNoCase(command, "up") == 0)
			printf("You went North\n");
		else if(StrCmpNoCase(command, "down") == 0)
			printf("You went South\n");
		getchar();
	}
	printf("Goodbye\n");
	return 0;
}

the %*c will read a character and discard it instead of writing it to a buffer. Under windows you're going to have to add another %*c to that scanf because pressing enter adds two residual char as opposed to a single char in linux.

Cheers.

uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-09 04:11:25 Reply

At 6/8/13 07:26 AM, kiwi-kiwi wrote: Uh, yeah, neither worked for me under linux for some reason, I recall using them under windows for homework for university, but I think there's something about the line buffering that linux terminals have. fflush(stdin) is undefined behaviour so gcc is free to do whatever they want, including nothing and the setvbuf call should have removed the line buffering altogether, but there's probably something the system does in the back that makes that call useless.

In any case here's something that works

:<<CODE<<


the %*c will read a character and discard it instead of writing it to a buffer. Under windows you're going to have to add another %*c to that scanf because pressing enter adds two residual char as opposed to a single char in linux.

Cheers.

But I still don't see how it skips the getchar(); command. But anyways: Thank you so much for taking the time to code for me. People using their free time to help me... I have no words :D

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-09 05:20:57 Reply

At 6/9/13 04:11 AM, uglybetty wrote: But I still don't see how it skips the getchar(); command.

Think of it like this, you have a bucket, and eve ry time you press a key, you add something to the bucket. When you press enter, scanf will take everything out of the bucket until it sees that something that looks like enter, on windows it's the \n\r and in linux it's just \n, they're called carriage return and line feed and they're 13 and 10, you can look them up on wikipedia to see where they originated and why they are separate because it's pretty interesting.

In any case, scanf finds the enter key, stops and leaves the enter key in the bucket. Now you call getchar, but scanf only saw that the enter key was pressed, it didn't actually take it from the bucket, so it's still there -> getchar takes it and returns.
This is why it doesn't stop and wait for you to press a key, you have to first empty the bucket, which is what fflush(stdin); theoretically does but might not work as it's undefined behaviour and this is why that %*c is there, it reads that character that pressing the enter key adds to the bucket, so that the next call to getchar stops the execution and waits for your input.

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-09 05:23:21 Reply

At 6/9/13 05:20 AM, kiwi-kiwi wrote:
At 6/9/13 04:11 AM, uglybetty wrote: But I still don't see how it skips the getchar(); command.
they're called carriage return and line feed and they're 13 and 10

Uh yeah, sorry, I got them mixed up, so \r is carriage return and it's 13 and \n is line feed and it's 10 and on windows it's \r\n not \n.
Cheers.

Filarius
Filarius
  • Member since: Aug. 16, 2005
  • Offline.
Forum Stats
Member
Level 14
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-10 08:31:53 Reply

At 6/9/13 05:23 AM, kiwi-kiwi wrote: Uh yeah, sorry, I got them mixed up, so \r is carriage return and it's 13 and \n is line feed and it's 10 and on windows it's \r\n not \n.

Need cross platform solutions, right ?

Windows >> \r\n
Unix >> \n
Mac >> \r

http://www.go4expert.com/articles/difference-n-rn-t8021/

So need check both \r and \n


<== This russian guy always write with mistakes.

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Text Adventure: cross platform lang 2013-06-10 13:06:44 Reply

At 6/10/13 08:31 AM, Filarius wrote: Need cross platform solutions, right ?

Windows >> \r\n
Unix >> \n
Mac >> \r

http://www.go4expert.com/articles/difference-n-rn-t8021/

So need check both \r and \n

I don't know what version of mac that guy used or where he got his information, but Mac OS X has received the UNIX 3 certification which means it's 100% a unix system since 10.5, so there is no way the line ending char is \r

Text Adventure: cross platform lang

Rawnern
Rawnern
  • Member since: Jan. 24, 2009
  • Offline.
Forum Stats
Member
Level 28
Movie Buff
Response to Text Adventure: cross platform lang 2013-06-12 15:27:10 Reply

Not sure if I understand you correctly. hope im right.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
   char path[80];
   while(1)
   {
        scanf("%s", path);
        if(strcmp (path,"up") == 0 || strcmp (path,"down") == 0)
        {
           break;
        }
        getchar();
   }
  // This code will be executed if the user types either up or down.
   return 0;
}

why it didn't work:

this condition will not be false - only true
while(strcmp (path,"one") != 0 || strcmp (path,"two") != 0)

No need to scan with an & before the variable path :)

uglybetty
uglybetty
  • Member since: Apr. 4, 2009
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Text Adventure: cross platform lang 2013-06-16 16:10:39 Reply

At 6/12/13 03:27 PM, Rawnern wrote: Not sure if I understand you correctly. hope im right.

why it didn't work:

this condition will not be false - only true
while(strcmp (path,"one") != 0 || strcmp (path,"two") != 0)

No need to scan with an & before the variable path :)

I don't think I understood de Morgans law completley. Ty for helping me out :D.