Drawing a text - error with argument in function "write"
As commented, adding write() as a callback in post_draw means it cannot have a parameter.

One solution would be to use your script as a python module. Code at the top of the script will be run once at game start, allowing you to initialise your module variables, then functions in the module can be used as needed. To be a module, the name of the text block must end in .py. For your first code example, you don't need to call write() at the bottom of your script, just naming it with .py should be all you have to do for it to work.

You can then use it in a python controller, set as a module, and call one of the functions based on the attached sensor. In this example I read a game property when the sensor runs the update(cont) function to update the modules chain property, the controller calling the function is passed in this case.



Text block "drawtext.py" -

# import game engine modules
from bge import render, logic
# import stand alone modules
import bgl, blf

# create a new font object, use external ttf file
font_path = logic.expandPath('//bmonofont-i18n.ttf')
# store the font indice - to use later
font_id = blf.load(font_path)
chain = 'this is the message'

def write():
    """write on screen"""
    width = render.getWindowWidth()
    height = render.getWindowHeight()
    # OpenGL setup
    bgl.glMatrixMode(bgl.GL_PROJECTION)
    bgl.glLoadIdentity()
    bgl.gluOrtho2D(0, width, 0, height)
    bgl.glMatrixMode(bgl.GL_MODELVIEW)
    bgl.glLoadIdentity()

    # BLF drawing routine
    blf.position(font_id, (width * 0.2), (height * 0.3), 0)
    blf.size(font_id, 50, 72)
    bgl.glColor4f(1.0, 0.0, 0.0, 1.0)
    blf.draw(font_id,chain)

def update(cont):
    own = cont.owner
    chain = own['msg']

# set the font drawing routine to run every frame
scene = logic.getCurrentScene()
scene.post_draw = [write]


You might use a property actuator to change the objects msg property, or a property sensor to run the update when the property changes. You can also import the module in another script and adjust the module property and call other functions.

import drawtext
drawtext.chain = 'New message'
drawtext.anotherfunc()