How to edit scripts after release?

Pages: 12
Hi
I know I asked a question lately and asking again isn't that good but it's important.
My question is pretty weird actually.I'm using Visual studio 2019 on Windows and I have developed a game. Now, I want the users to be able to edit specific files in the program after the release without them having to install c++ program/compiler,they will just edit them in the notepad for example, the program just updates itself.

Quick example to explain myself:

Main:

#include <iostream>
#include "Header.h"

using namespace std;


int main()
{
say_hello();
system("pause");
return 0;
}


Header file:------------
#pragma once
#include <iostream>
using namespace std;
void say_hello()
{
cout << "Hello!\n";



}

OUTPUT: Hello!


Now let's say that I changed the say_hello function to print "Hi!" through the notepad after the release and the exe program updates to output: Hi!





Your users don't have the C++ code.

When you compile your C++ code, it creates a binary executable file. The user gets that. That file does not contain C++ code. The user does not have your C++ code and there is no way that they can edit the C++ code. Even if you gave them the C++ code and they edited it, they would then have to recompile it.

C++ is not an interpreted language in which an interpreter reads a script at runtime. C++ is a compiled language (that's why we don't call C++ source code a "script").

If you want the behaviour of the program to change, you have two choices:

1) The user has to receive a new version of your executable or library.
2) Your program comes with some kind of configuration file that the user CAN edit. Your program reads that file when it runs, and uses the contents of that file to control what happens.
Last edited on
Yeah,I am aware of that problem. About option 2, is there a way to use text file as header file? After all,header file is a sort of a text file.
Header files are text files (as are source files). You already use text files as header files.

At compilation time, the header files and source files are read and then that's it. Never used again. Giving your users a header file along with the binary executables will be of no use, as the compilation is already done.
Last edited on
Ok understood,what about reading a text file and then compile the code? I mean,the text file contains the code and the header/source file (which is not accessible to the user) reads the text file and compiles it.Is that even possible?
1. Don't put code (except inline functions and templates) in header files.

2. If you want user edit-ability, then provide a text file.
1
2
3
4
5
6
void say_hello()
{
    ifstream inf("messages.txt");
    inf >> message;
    cout << message;
}

Your users can edit messages.txt to be whatever they want.

But apply plenty of error checking for things like
- the file is missing
- the file is unreadable
- the file is a binary file, say audio, video, executable
- the file is a text file, but extremely large.
Ok
I really think I didn't explain myself right. I want to have a text that contains some code,for example,the say_hello function,the whole body of the function is in this text file(the function's declaration is in the main code ).In my main code I'll read the text file,get the code and compile it and then run the code like any other code file.

The thing I am looking for is kind of similar to how GLSL works

Think about a project where we have main.cpp file functions.h file (where say_hello is declared) and instead of functions.cpp there will be a text file that contains the body of say_hello
In my main code I'll read the text file,get the code and compile it and then run the code like any other code file.


And you want this to happen on the user's machine? You want the user to be able to compile C++ code, and create a whole new binary program, but you also want that to happen without the user installing a C++ compiler?

Given that it's impossible to compile C++ code without a C++ compiler, and you don't want the user to have to install a C++ compiler, there seems to be a bit of a contradiction here.

The thing I am looking for is kind of similar to how GLSL works
That uses a compiler. The GLSL code gets compiled, with a compiler.

then run the code like any other code file
In C++, code files don't get run. Code files (being text files containing C++ code) get used by the compiler to make a whole new, completely different program, and THAT whole new completely different program is run. The thing that runs contains NO C++ code.


It sounds like you want the user to be able to write scripts that your already compiled program will then read and interpret. Like your program is a Python interpreter, or a LUA interpreter This is fairly common, but those scripts are not written in C++. It's also not very easy, especially for a beginner, but it can be done. You pick a scripting language, you bundle an interpreter for that language with your program, and then at runtime your program runs that interpreter, and that interpreter reads a script the user wrote. This can be done because scripting languages are not compiled; they are read at runtime.

Last edited on
It is possible but not really easy.

If you don't want a compiler installed you can send the source file to a server in the internet which replies a dll.
You can load the dll and search for the function by its name and if found execute that function.
It seems to me the OP should just publish their git repo and be done with it, if the game is so incomplete and unconfigurable that source code editing is the only way to solve the problem.

If the users NEED a compiler, then they're no longer players, but developers.

Even if you imagined that this was possible, 99% of the users won't have any clue about programming, and will find millions of ways to screw it up one way or another.
1
2
3
4
5
6
7
#pragma once
#include <iostream>
using namespace std;
void say_hello()
{
    cout << "Hello!\n";
}

Do you really want to spend your life explaining the missing ; or some other trivial nonsense.

I'm wondering if the OP is really asking about internationalisation, and it's not really about changing "Hello" into "Hi", but more about changing "Hello" into "Bonjour".

This does have all the feeling of an http://xyproblem.info/
I would think that the OP is asking for a plugin mechanism.

I would also assume that someone who knows how to program will surely have a compiler installed.
@coder777, that's what I was thinking.

Yet, I also thought this sounds like a plan for disaster.

It is more common to implement a scripting language for such things for users.

On the other hand, this is, somewhat generally, how some game engines are built. The game engine is fashioned into a game editor/designer, and the consumer (a programmer) builds C++ code, building a result product or plugins to the editor.

That is not for the game player, but for the programmer consuming the game engine.
Sorry for annoying you guys, let me explain.
I just made a demake for my Ldum Dare game. I made the game engine so that making stuff work is simple as rectangle.move(1,0). I just want as an added bonus to the demake edition a built in level maker for the users. Customizing the walls of the level is very simple(Just redraw the level in the notepad).All the other and more interesting elements of the game( like moving lasers) are created and function though the code itself. So I have thought that maybe you can change the body of the elements functions (e.g. the function that mange all of the machine guns in the game) and the game will update.

All I want is a level maker in my game.
Sure. These functions that are used to manage the machine guns. You can change them so that they get their information from a plain text file that they read at runtime. Then, the user needs only change that text file.
That sounds nice but I don't really know how to do it. I want the user to use my actual commands.
For example:

There are more loop and annoying stuff in the function but I want to save time.
The function before :
1
2
3
4
5
6
7
8
9
10
11
12
13
14

MG machine1(constractor stuff)
for(int i=0;i<10;i++)
{
   machine1.shoot(1,0);
   machine1.move(1,0);
   Sleep(70);
}
for(int i=0;i<10;i++)
{
   machine1.shoot(1,0);
   machine1.move(-1,0);
   Sleep(70);
}


Now let's say that the designer want the machine gun to move and then shoot.
So the text file looks like that now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

MG machine1(constractor stuff)
for(int i=0;i<10;i++)
{
  machine1.move(1,0);
  machine1.shoot(1,0);
   Sleep(70);
}
for(int i=0;i<10;i++)
{
   machine1.move(-1,0);
   machine1.shoot(1,0);
    Sleep(70);
}


And now the function will do it. How this can be done? Or you talking about something else?
there is no simple fix. you need to recode some of this to do what you want.
it could look like this:

userfile >> what; //move or shoot or ...
usefile >> value;

if(what == "shoot")
{
machine1.shoot(value);
}
if( what == "move)
{
machine1.move(value);
}
and so on.
you probably read the file one time and make a list of things to do (maybe 2 lists, initial setups and actions, dunno) and then iterate those lists (setup once, actions every time) to do the things you want.

machine1 is probably also from a list of objects that you let the user define in the file, so then you have a list of things each with its own list of setups and actions, perhaps...
we can't tell you exactly because we lack details but does this make sense?
yes, its a bit of work. Configurable programs require some up-front design about how it all plays together so you can do it efficiently and cleanly in the code.
you need to stop coding, and list out all the things you want the user to be able to define/create/etc, and then go over that carefully as to how you can get that from a text file into your program with the least amount of trouble. You also need to make this FLEXIBLE so if you add a new thing to the code, its easy to add it to your infrastructure and text file so that it works with only a little more code to support it.
Last edited on
If you have something like this in the textfile:

1
2
3
MOVE 1 0
SHOOT 1 0 
SLEEP 70


Then this:

1
2
3
4
5
6
for(int i=0;i<10;i++)
{
   machine1.shoot(1,0);
   machine1.move(1,0);
   Sleep(70);
}


could become something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for(int i=0;i<30;i++)
{
  // READ NEXT WORD FROM INPUT FILE
  string word;
  inputFile >> word;

  if (word == "MOVE")
  {
    int valOne;
    int valTwo;
    inputFile >> valOne;
   inputFile >> valTwo;

     machine1.move(valOne, valTwo);
  }
  else if (word == "SHOOT")
  {
    // Do similar here to read next section etc
  }
  else if (word == "SLEEP")
  {
   // and so on
  }
}


This would require you opening the text file and reading it, which is not very difficult: http://www.fredosaurus.com/notes-cpp/io/readtextfile.html

You'd need to do some basic error checking, for unexpected words or people forgetting the numbers etc

The format of the text file is completely up to you. If you made the text file:
1
2
3
 machine1.shoot(1,0);
   machine1.move(1,0);
   Sleep(70);

which carries the same information but is harder for the user to write, this is much harder to work with because now you have to parse out the brackets and commas and outer punctuation, but you can still do it.
Last edited on
@odglog, both @jonnin and @repeater are illustrating a simple version of something commonly done in scripting applications (not just games, but many different script-able applications).

This is loosely related to "undo" systems, too.

The basic notion is that the "stuff" that is to be scriptable by the user is fashioned as a series of commands. This is what is illustrated simply in both of the previous posts, where a string command is matched to an "if" clause (or some table of commands), where the command "fires" the matching script command.

This is a simple approach.

Taken to the next step, one creates a language. There are "pre-built" scripting libraries, some for lua, some for javascript (which, you may recognize, is a major scripting application common to web browsers).

These more complex, formalized systems fashion objects for the commands. The commands themselves may be implemented by some mechanism like "std::function", "std::bind", or some similar "callable object" mechanism.

The application then operates as an executive running these commands.

This technique is beyond exemplifying in an 8K post here. You would probably be better served by searching for a lua scripting library intended for game scripting.

What you are thinking about doing is a reasonably complex concept, and it is done widely in games, but none offer the user the ability to compile and run their own C++ code. That's a disaster, because they'd have to be competent C++ programmers to do that, and you'd end up in a support nightmare situation with everyone using the product complains about everything they can't handle in C++ themselves. You'd have to start a website like this one just to handle the discussions.

Games themselves are among the most complex things built. Not necessarily the most complex, but well into the category of the most complex demands on everything from language features to CPU/GPU power.

If you are studying the subject, and therefore building a game from scratch just to understand how it is done, that's a worthy direction. It is a necessary teaching/learning tactic to engage the study of low level, highly complicated implementations of various concepts just so we develop new engineers capable of making them.

If your goal is to make a game, however, then you are going to have to face a simple fact: in the modern era (anything this side of the late 1990's), you quickly run into design requirements which are far too complex for one person to write, and the only reasonable conclusion is to choose a game engine.

The good news is that many or most have built in scripting solutions you can merely access for your design.

If you want to understand the basics of how a scripting system is implemented, you'll need to study how parsers are built, and how to create and use callable objects (like std::function, std::find, pointers to functions, pointers to member functions).

Those are the minimal prerequisites to "doing this right".

There is another, related notion common to GUI applications. In the old style, all of the processing of input from the mouse, the keyboard, clicked buttons, etc. are handled through message (using the message paradigm). Modern GUI frameworks react to this by creating a means of matching those messages (they are like the keywords "shoot" and "move" in the scripting context) to the functions that respond to them using basically the same things: std::bind, std::function and related concepts.

Now, if that isn't clear enough, let me paint the picture this way.

Imagine that you can create an array, where each entry in the array is a function you can call by number. If "shoot" is 5, and "move" is 7 (and lots of other "instructions" in this array range from zero to maybe 50 or more), then you can call a function (to move, or shoot, or whatever) using an entry from that array.

That means function calls can be presented as data.

That is central to the notion of turning a "key" (like the words "shoot" and "move") into a call to a function that does something. This is central to message paradigms and to scripting paradigms.

Wow, thanks for the help everyone!
According to @Niccolo's last section and other people advised I can create my own "scripting language" by making a function call array and by writing it in the text file it will "compile" it and then call the keyword's index function? Correct me if I'm wrong.
Pages: 12